Another Salesforce blog!!!

Salesforce, Apex

how to retain the checkbox selection in visualforce pagination


First off; create a wrapper class in this example I’ll be using Account standard object:

Overall big picture:

  1. First on the Visualforce page create apex function with two params.
  2. Create a SET variable of id’s(Set some name = new Set)
  3. Create two properties (get; set; method properties) for Id and another for boolean.

Now the logic goes like this

  • You are fetching the tableData on VF page.
  • If you select any checkbox in that result at datatable, it should call the above Apex function by passing the selected status and selected id.
  • The Apex function in turn calls the void method in controller by setting the the select status and select id to the properties mentioned above (#3)
  • In the void method all we are doing is checking the selected status, if True add the id to set variable. If False remove the id from set variable.
  • After you do this, you can just iterate through wrapper class results to see if the id is present in the set variable and make the selected value of wrapper class to true else false. This way when you do the pagination, the wrapper class results are called always and it checks if the checkbox selected status should true of false before returning the results to VF page.

Step 1:

Lets create wrapper Apex Class:

public class PaginationWrap { 

    public Boolean checked {get;set;} 
    public Account act {get;set;}
    public Decimal quantity {get;set;}
    public PaginationWrap(Account a){
        act = a;
        checked = false; 
        quantity = 0;
    }
}

Step 2:

Create Visualforce page:

<apex:page controller="PaginationController">
    
    <apex:form id="form">
        
        <apex:actionFunction name="aSelectItem" action="{!doSelectItem}" rerender="pb">
            <apex:param name="contextItem" value="" assignTo="{!contextItem}"/>
        </apex:actionFunction>
        <!-- handle deselected item -->
        <apex:actionFunction name="aDeselectItem" action="{!doDeselectItem}" rerender="pb">
            <apex:param name="contextItem" value="" assignTo="{!contextItem}"/>
        </apex:actionFunction> 
        
        <apex:actionFunction name="isSelectAllItem" action="{!isSelectedAll}"  rerender="pb">
            <apex:param name="isSelectedALL" value="" assignTo="{!selectedAllProperties}"/>
        </apex:actionFunction>
        
        <apex:actionFunction name="updateQuantity" action="{!updateQuantity}" rerender="pb">
            <apex:param name="contextItem" value="" assignTo="{!contextItem}"/>
            <apex:param name="contextItemValue" value="" assignTo="{!contextItemValue}"/>
        </apex:actionFunction>
        
        <apex:pageBlock title="Account Details" id="noRec" rendered="{! IF(AccountWraps != null && AccountWraps.size ==0 , true, false)}" >
            <apex:outputPanel >
                <h1>No Records Found </h1>
            </apex:outputPanel>
        </apex:pageBlock>
        
        <apex:pageBlock title="Account Details" id="pb" rendered="{! IF( AccountWraps != null && AccountWraps.size >0, true, false)}" >
            <apex:pageMessages ></apex:pageMessages>
            <apex:pageBlockButtons >
                <apex:commandButton value="Save Selected" action="{!saveSelected}"/>                              
            </apex:pageBlockButtons>
            
            <apex:pageBlockTable value="{!AccountWraps}" var="a" id="pbt">
                <apex:column >
                    <apex:facet name="header">
                        <apex:inputCheckbox value="{!selectedAllProperties}" onclick="selectAllCheckboxes(this)" />
                    </apex:facet> 
                    <apex:inputCheckbox value="{!a.checked}" styleClass="cbStyleClass" onclick="doCheckboxChange(this,'{!a.act.Id}')" />
                </apex:column>
                <apex:column headerValue="Agent Commission Percentage">
                    <apex:inputText value="{!a.quantity}" onchange="updateTextChange(this, '{!a.act.Id}')"/>
                </apex:column>
                <apex:column headerValue="Account Name">
                    <apex:outputLink target="_blank" value="/{!a.act.id}">{!a.act.Name}</apex:outputLink> 
                </apex:column>  
                <apex:column value="{!a.act.accountNumber}" headerValue="Account Number"/>  
                <apex:column value="{!a.act.Industry}" headerValue="Industry"/>  
                <apex:column value="{!a.act.AnnualRevenue}" headerValue="Annual Revenue"/>  
                <apex:column value="{!a.act.Phone}" headerValue="Phone"/>   
                <apex:column value="{!a.act.website}" headerValue="Web"/>    
            </apex:pageBlockTable>
            
            <apex:outputPanel >
                <br/>
                <!-- count of selected items -->
                <apex:outputLabel value="{!selectedCount} Accounts Selected" />
            </apex:outputPanel>
            <br/> 
            <!--PAGINATION outputPanel-->
            <apex:outputPanel rendered="{!AccountWraps.size>0}" styleClass="center">
                <apex:commandButton status="st" reRender="pb" value="|< First" action="{!first}" disabled="{!!hasPrevious}" title="First Page"/>
                <apex:commandButton status="st" reRender="pb" value="Previous" action="{!previous}" disabled="{!!hasPrevious}" title="Previous Page"/>
                <apex:outputText > &nbsp;Page {!(pageNumber * size)+1-size} of {!IF((pageNumber * size)>noOfRecords, noOfRecords,(pageNumber * size))} of total {!noOfRecords}</apex:outputText>&nbsp;
                <apex:commandButton status="st" reRender="pb" value="Next" action="{!next}" disabled="{!!hasNext}" title="Next Page"  />
                <apex:commandButton status="st" reRender="pb" value="Last>|" action="{!last}" disabled="{!!hasNext}" title="Last Page"/>
                
                <apex:outputPanel style="color:#008000;font-weight:bold">
                    <apex:actionStatus id="st" startText="Fetching..." stopText=""/>
                </apex:outputPanel>
            </apex:outputPanel> 
        </apex:pageBlock>
    </apex:form>
    
    <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
    <script type="text/javascript">
       
    //function to handle checkbox selection
    function doCheckboxChange(cb,itemId)
    {
        if(cb.checked==true){
            aSelectItem(itemId);
        }
        else{
            aDeselectItem(itemId);
        }        
    }    
    function selectAllCheckboxes(obj){
        $(".cbStyleClass").each(function(index, item){
            item.checked = obj.checked;
        });
        isSelectAllItem(obj.checked);
    }
    
    function updateTextChange(obj, itemId){
        
        updateQuantity(itemId, $(obj).val());
    }
    </script>
    
</apex:page>

Step 3:

Create PaginationController:

public with sharing class PaginationController 
{ 
    //Pagination Standard Set
    public ApexPages.StandardSetController con;
    
    public Map<Id, Decimal> quantityMap {get;set;}
    public Set<Id> selectedPropertyIds {get;set;}
    public String contextItem {get;set;}
    public String contextItemValue {get;set;}
    public Boolean selectedAllProperties {get;set;}
    
    /** handle item selected */
    public void doSelectItem()
    { 
        this.selectedPropertyIds.add(this.contextItem);
    }
    
    /** handle item deselected */
    public void doDeselectItem()
    {
        this.selectedPropertyIds.remove(this.contextItem);
    }
    
    public void isSelectedAll()
    {
        for (sObject record : this.con.getRecords()){
            Account a = (Account) record;
            if(selectedAllProperties){
                this.selectedPropertyIds.add(a.id);
            }else{
                this.selectedPropertyIds.remove(a.id);
            }
        }
    }
    
    public Integer getSelectedCount()
    {
        return this.selectedPropertyIds.size();
    } 
    
    public PaginationController()
    {         
        this.selectedPropertyIds = new Set<Id>();
        this.quantityMap = new Map<Id, Decimal>();
        size= 5;
        init();
    }
    
    public void init() 
    {
        this.con = new ApexPages.StandardSetController([SELECT Id,Name,AccountNumber,CreatedDate,Phone,Website,Industry,AnnualRevenue From Account ORDER BY Name  ASC, CreatedDate DESC LIMIT 50000] );
        this.con.setpageNumber(1);
        this.con.setPageSize(size);
        noOfRecords = this.con.getResultSize();  
    }
    
    public void updateQuantity()
    {
        this.quantityMap.put(this.contextItem, Decimal.valueOf(this.contextItemValue));
    }
    
    public List<PaginationWrap> getAccountWraps() 
    {
        List<PaginationWrap> accountWraps = new List<PaginationWrap>();
        Integer selectedPropertyNumber = 0;
        
        for (sObject record : this.con.getRecords())
        {
            Account a = (Account) record;
            PaginationWrap currentWrap = new PaginationWrap(a);
            //for the inputText
            if(quantityMap.containsKey(a.id))
            {
                currentWrap.quantity = quantityMap.get(a.id);
            } 
            //for the checkbox:
            if(this.selectedPropertyIds != null) 
            {
                if(this.selectedPropertyIds.contains(a.Id)){
                    currentWrap.checked = true;
                    selectedPropertyNumber ++; //show the checkbox selected count
                }
                else{
                    currentWrap.checked = false;
                }
            }
            accountWraps.add(currentWrap);
        }
        selectedAllProperties = selectedPropertyNumber == accountWraps.size() ? true: false; 
        return accountWraps; 
    } 
    
    public void savingSelectedRecords()
    {  
        for (Id key : quantityMap.keySet()) {
            // The "key" variable is also available inside the loop
            system.debug('map key: ' + key +  '  map key value: ' + quantityMap.get(key)); 
        }  
    } 
    
    public PageReference saveSelected() 
    {
        try{
            savingSelectedRecords();
        }
        catch(DmlException dmlException){
            Integer numErrors = dmlException.getNumDml();
            for(Integer i=0; i< numErrors; i++){
                ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Error, dmlException.getDmlMessage(i)));
            }
            return null;
        }
        catch(Exception e){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Error, e.getMessage()));
            return null;
        } 
        return null;
    }
    
    // If the pagiantion has next page 
    public Integer size {get;set;}
    public Integer noOfRecords{get; set;}
    public Boolean hasNext {
        get {
            return con.getHasNext();
        }
        set;
    }
    
    //Indicates whether there are more records before the current page set.
    public Boolean hasPrevious {
        get {
            return con.getHasPrevious();
        }
        set;
    }
    
    //returns the page number of the current page set
    public Integer pageNumber {
        get {
            return con.getPageNumber();
        }
        set;
    }
    
    public Integer totalPageNumber {
        get {
            Decimal totalSize = this.con.getResultSize();
            Decimal pageSize = this.con.getPageSize();
            Decimal pages = totalSize/pageSize;
            return (Integer)pages.round(System.RoundingMode.CEILING);
        }
        set;
    }
    
    /**
* Go to the first page directly
*/
    public void first() {
        con.first();
    }
    
    // returns the last page of records
    public void last() {
        con.last();
    }
    
    // returns the previous page of records
    public void previous() {
        con.previous();
    }
    
    // returns the next page of records
    public void next() {
        con.next();
    } 
}

Output:

Leave a Reply

Your email address will not be published. Required fields are marked *

*