function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
SoozeeSoozee 

How to pass record id to controller from vf page with checkbox 'onclick'

Hi - I want to dynamically update a record when a user clicks a checkbox on my vf page, but I cannot figure out how to pass the record id of the row that is clicked to the Controller.

 

 

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
JconsultantJconsultant

Try this:

 

create a variable in your controller

 

public String selectedLetterID {get;set;}

 

Then set it with the param tag.

 

<apex:inputfield value="{!letter.Suppressed__c}" id="suppressBox" onclick="SupressLetter('{!letter.Id}');return false;"/>

 

 

<apex:actionFunction name="SupressLetter" action="{!suppressLetter}" rerender="out">

    <apex:param name="firstparam" assignto="{!selectedLetterID}" value="" />

</apex:actionFunction>

 

Then update your record based on the id that is now assigned to your new variable in your controller method.

 

All Answers

bob_buzzardbob_buzzard

Can you give us a little more information - it sounds like you are using a table or repeat, is that correct?  How are you generating the collection of records the user can choose from?

SoozeeSoozee

Sorry for the lack of information, here is more...

 

I am displaying information in a table.  The table is populated by a SOQL query in my controller.

The value of the checkbox is an actual field in the object.  Here is where I define the column containing the checkbox in the vf page:

 

<apex:column >
<apex:facet name="header" >

<!-- this makes the column sortable -->
<apex:outputLink onclick="SortBySuppressed();return false;">Suppressed</apex:outputLink>

</apex:facet>

 

<!-- this is the checkbox that I want to make work like a button -->
<apex:inputfield value="{!letter.Suppressed__c}" id="suppressBox" onclick="SupressLetter();return false;"/>
</apex:column>

 

 

And then SupressLetter() calls:

 

<apex:actionFunction name="SupressLetter" action="{!suppressLetter}" rerender="out"/>

 

And suppressLetter is a PageReference in my controller that updates the record selected, but I can't figure out how to pass the record id to the controller from the VF page.

 

Thanks for your time!

 

 

SoozeeSoozee

Since I couldn't figure out how to identify the selected row, I just updated all rows and this solved my immediate issue.

JconsultantJconsultant

Try this:

 

create a variable in your controller

 

public String selectedLetterID {get;set;}

 

Then set it with the param tag.

 

<apex:inputfield value="{!letter.Suppressed__c}" id="suppressBox" onclick="SupressLetter('{!letter.Id}');return false;"/>

 

 

<apex:actionFunction name="SupressLetter" action="{!suppressLetter}" rerender="out">

    <apex:param name="firstparam" assignto="{!selectedLetterID}" value="" />

</apex:actionFunction>

 

Then update your record based on the id that is now assigned to your new variable in your controller method.

 

This was selected as the best answer
SoozeeSoozee

Thanks, I'll try this.

SoozeeSoozee

Hi - Your solution works great, however...
From the time I click the checkbox, it takes 4 whole seconds for the check in the checkbox to appear.

This will cause users to think that their initial click didn't work, causing them to click several times.  In essence,  checking and unchecking the checkbox several times and not seeing the immediate result on the screen.

 

Any suggestions for reducing the lag?

 

Here is the method in the controller that handles the update:

 

public PageReference suppressLetter(){
     	system.debug('selected Letter ID = '+selectedLetterID);
     	List<Letter__c> letterToUpdate = [select suppressed__c from Letter__c where id =  :selectedLetterID];
     	for (Letter__c l : letterToUpdate){     		
	     	if (l.suppressed__c == FALSE){
	     		l.suppressed__c = TRUE;
	     	}
     	}
     	update letterToUpdate;     	
     	return null;
     }

 

bob_buzzardbob_buzzard

This is likely to be the way visualforce works.  The postback requires serialize/deserialize of the view state.  You could try using the view state inspector to see if you can reduce the size.

JconsultantJconsultant

It looks like you're doing SOQL, a FOR loop through the results, then a DML operation all in your onclick method.  Is there anyway you can perform these operations at a different point in your flow?  Performance is usually pretty good when you are just setting a parameter and re-rendering a section of the page.  Another thought would be to use the ActionStatus tag to let users know you are working on something behind the scenes.  4 seconds is unacceptable.

JconsultantJconsultant

You should have a list of records that were returned in your table.  If the requirement is to update a record based on a checkbox click, then I would do an update on that record that looked something like this.

 

 

Letter__c letter = new Letter__c(id=SELECTEDID.....whatever other fields you want updated);

try{

update letter;

}

catch(exception e){

//handle your exception here.

}

 

If you need to know if a boolean is checked on that record, I would pull that in the original SOQL query for the list that is returned in your table.  Put the results in a map that can be accessed using the id they select.  

SoozeeSoozee

Hi - So, I added the query results to a map and then referenced the map when the checkbox is clicked.  I am down to two seconds from four, but this is still noticeably slow.

 

Here is where I add the query results to the map:

 

Public Void populatePage(){
	studentList = [select Id, account__r.college__c, Letter_Type__c, Suppressed__c, Reviewed__c, Reduced_Course_Load__c, Status__c, Attention__c, account__r.name, Letter_Body__c, Date_Processed__c, Date_Printed__c, Date_Emailed__c, account__r.FirstName, account__r.LastName, account__r.Primary_Advisor__c from Letter__c where account__r.Primary_Advisor__c = :advID and term__c = :activeTerm];

	// add query results to map
	for (Integer i=0;i<studentList.size();i++) {
		studentListSupMap.put(studentList[i].id,studentList[i].suppressed__c);
	}
}

 Here is where I call the function from the page:

 

public PageReference suppressLetter(){
     	system.debug('selected Suppressed Letter ID = '+selSupLetterID);
     	// get boolean value from map
     	
     	
     	if(studentListSupMap.get(selSupLetterID) == FALSE){   	
	     	Letter__c updateSupLetter = new Letter__c(id=selSupLetterID,suppressed__c=TRUE);
			try{
				update updateSupLetter;
			}
			catch(exception e){
			//handle your exception here.
			}
     	}else if (studentListSupMap.get(selSupLetterID) == TRUE){   	
	     	Letter__c updateSupLetter = new Letter__c(id=selSupLetterID,suppressed__c=FALSE);
			try{
				update updateSupLetter;
			}
			catch(exception e){
			//handle your exception here.
			}
     	}
     	return null;
     }

 Any other suggestions?  Thank you!

SoozeeSoozee

Actually, it's not any faster the new way. I was just counting slower :)

JconsultantJconsultant

Do you have "Developer Mode" turned on for your user account?  That slows down the page performance.

SoozeeSoozee

Hi - I do not have 'Developer Mode' turned on.

SoozeeSoozee

Hi - I am trying to implement the ActionStatus suggestion to no avail.  I can't seem to get the action 'updating...' to appear on the page.  Help?

Action Function:

 

<apex:actionFunction name="SupressLetter" action="{!suppressLetter}" rerender="out" status="SuppressStatus">
     <apex:param name="firstparam" assignto="{!selSupLetterID}" value="" /> 
   </apex:actionFunction> 

 

<apex:column >    
                            <apex:facet name="header" >
                                <apex:outputLink onclick="SortBySuppressed();return false;">Suppress</apex:outputLink>
                            </apex:facet>
                             <apex:inputfield value="{!letter.Suppressed__c}" id="suppressBox" onclick="SupressLetter('{!letter.Id}');return false;"/>
                            <apex:actionStatus startText="updating..." id="SuppressStatus"/>
        
                            </apex:column>

 

SoozeeSoozee

Got this to work with some javascript...  The page still takes 4 seconds to return, but at least now the user is aware that the page is doing something.