May 02

Print this Post

Pagination using StandardSetController with wrapper class

Pagination using StandardSetController with wrapper class without losing data during pagination

Click here for Demo – Pagination with wrapper

Very often, we need pagination in our visualforce page, and we use wrapper class to show the records with checkboxes in pageBlockTable. We use the standardSetController for pagination, display checkboxes for each record BUT while paginating, the value of the selected checkboxes are gone, it doesn’t retain during paginating.

This is because the list that we use to display records on page, is getting refreshed everytime, and not retaining the values. So, to hold or retain the values during pagination, we will see how we can use Pagination using StandardSetController with wrapper class without losing data during pagination/ paginating (moving next or previous).


PaginationImage,Pagination using StandardSetController with wrapper class

Contact pagination – Wrapper Class – With checkboxes


So, to overcome this, we will not use the direct list from standardSetController, instead of that we’ll use a map to show the values on page. This map will always contain the correct values of checkboxes (for retaining purpose), we will use map on visualforce page pageBlockTable. Whenever user clicks on next or previous, first or last, we store the copy of records with checkbox value in map, so that even if the wrapper list is refreshed with next set of records, we can store the checkbox values for previous set of records.

Below is the code snippet you can look at, and we have a demo link as well, just to give you an idea how it works.

Visualforce Page Code:

<apex:page controller="contactPaginationController" docType="html-5.0" tabStyle="Contact">
   <apex:sectionHeader title="Contact" subtitle="Contact Pagination" />
    <apex:form id="theForm">
      <apex:pageBlock title="All Contacts" rendered="{!wrapperRecordList.size!=0}" id="pbId" >
        <apex:pageBlockTable value="{!wrapperRecordList}" var="cont">
           <apex:column headerValue="Select">
             <apex:inputCheckbox value="{!cont.isSelected}"/>
           <apex:column headerValue="Name">
             <apex:outputField value="{!cont.contactRecord.name}"/>
           <apex:column headerValue="Email">
             <apex:outputField value="{!cont.contactRecord.Email}"/>
           <apex:column headerValue="Phone">
            <apex:outputField value="{!cont.contactRecord.Phone}"/>

 <!-- Action Buttons visible on bottom of page for pagination -->
       <apex:outputPanel style="text-align:center;" layout="block">
          <apex:commandButton value="First" reRender="pbId" action="{!first}" disabled="{!NOT(hasPrevious)}" status="paginationStatus"/>
          <apex:commandButton value="Previous" rerender="pbId" action="{!previous}" disabled="{!NOT(hasPrevious)}" status="paginationStatus"/>&nbsp;Page {!pageNumber} of {!totalPages}&nbsp;
          <apex:commandButton value="Next" rerender="pbId" action="{!next}" disabled="{!NOT(hasNext)}" status="paginationStatus"/>
          <apex:commandButton value="Last" rerender="pbId" action="{!last}" disabled="{!NOT(hasNext)}" status="paginationStatus"/>
          <apex:actionStatus id="paginationStatus">
             <apex:facet name="start">
                 Please wait...<img src="/img/loading32.gif" style="width: 18px;"/>

Apex Controller:

public class contactPaginationController{

 //variable used in page.
 Public Integer size{get;set;}
 Public Integer noOfRecords{get; set;}
 public List<SelectOption> paginationSizeOptions{get;set;}
 public static final Integer QUERY_LIMIT = 10000;
 public static final Integer PAGE_SIZE = 5;

 public List <WrapperClass> wrapperRecordList{get;set;}
 Map<Id, WrapperClass> mapHoldingSelectedRecords{get;set;}

 //constructor calling init method.
 public contactPaginationController(){
   mapHoldingSelectedRecords = new Map<Id, WrapperClass>();


//Init method which queries the records from standard set controller.
 public void init() {
 wrapperRecordList = new List<WrapperClass>();
 for (Contact cont : (List<Contact>)setCon.getRecords()) {
 if(mapHoldingSelectedRecords != null && mapHoldingSelectedRecords.containsKey(cont.id)){

   wrapperRecordList.add(new WrapperClass(cont, false));

 /** Instantiate the StandardSetController from a query locater*/
 public ApexPages.StandardSetController setCon {
 get {
 if(setCon == null) {
   setCon = new ApexPages.StandardSetController(Database.getQueryLocator([SELECT Id,Name, Email, Phone FROM Contact LIMIT : QUERY_LIMIT ]));

   // sets the number of records to show in each page view
   return setCon;

 /** indicates whether there are more records after the current page set.*/
 public Boolean hasNext {
 get {
   return setCon.getHasNext();

 /** indicates whether there are more records before the current page set.*/
 public Boolean hasPrevious {
 get {
   return setCon.getHasPrevious();

 /** returns the page number of the current page set*/
 public Integer pageNumber {
 get {
   return setCon.getPageNumber();

 /** return total number of pages for page set*/
   Public Integer getTotalPages(){
     Decimal totalSize = setCon.getResultSize();
     Decimal pageSize = setCon.getPageSize();
     Decimal pages = totalSize/pageSize;
     return (Integer)pages.round(System.RoundingMode.CEILING);

 /** returns the first page of the page set*/
 public void first() {

 /** returns the last page of the page set*/
 public void last() {

 /** returns the previous page of the page set*/
 public void previous() {

 /** returns the next page of the page set*/
 public void next() {

 //This is the method which manages to remove the deselected records, and keep the records which are selected in map.
 private void updateSearchItemsMap() {
 for(WrapperClass wrp : wrapperRecordList){
     mapHoldingSelectedRecords.put(wrp.contactRecord.id, wrp);
  if(wrp.isSelected == false && mapHoldingSelectedRecords.containsKey(wrp.contactRecord.id)){

 //wrapper class being used for checkbox showing.
 public class WrapperClass {
 public Boolean isSelected {get;set;}
 public Contact contactRecord {get;set;}
 public WrapperClass(Contact contactRecord, Boolean isSelected) {
    this.contactRecord = contactRecord;
    this.isSelected = isSelected;


Click here for Demo – Pagination with wrapper

This is just an example we are taking here (i.e. display contacts with checkboxes), there can be several other scenarios as well, where you might have some inputField in one column of the pageBlockTable, and you need to retain the values of inputfield during pagination.

There also you can use this concept of Pagination using StandardSetController with wrapper class without losing data during pagination.

This is also very important because this kind of scenario is included for sure in Advanced Developer certification exam exercise, where you have to do pagination with either checkboxes or inputField in pageBlockTable.

Hope this post will give you a better idea about pagination and that too with wrapper classes.

Happy coding !! :)

Permanent link to this article: http://www.sfdcpoint.com/salesforce/pagination-using-standardsetcontroller-with-wrapper-class/