Problem :-
1) One thing I noticed is the Checkboxes don’t maintain state in pagination with StandardSetController if you check one, go to the next page, then go back. Checkbox will uncheck again.
2) StandardSetController only support List of Sobject and SOQL as parameter. Some time in our case we did not use the SOQL and Sobject. We need to create Wrapper class and need to show that wrapper class with pagination on Visual force page.
Please check Working on below link :-
http://amitblog-developer-edition.ap1.force.com/apex/CustomPaginationDemo
Step 1:- Create Wrapper Class :-
Step 3:- Create controller class :-
Step 4:- Create Visual Force Page :-
Related Link :-
Standardsetcontroller Reference:- https://www.salesforce.com/us/developer/docs/pages/Content/apex_pages_standardsetcontroller.htm
https://www.salesforce.com/us/developer/docs/pages/Content/apex_ApexPages_StandardSetController_constructors.htm
Standardsetcontroller Eaxmple :-
http://blog.jeffdouglas.com/2009/07/14/visualforce-page-with-pagination/
Iterable Class Detail:-
https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_iterable.htm
Thanks
Amit Chaudhary
1) One thing I noticed is the Checkboxes don’t maintain state in pagination with StandardSetController if you check one, go to the next page, then go back. Checkbox will uncheck again.
2) StandardSetController only support List of Sobject and SOQL as parameter. Some time in our case we did not use the SOQL and Sobject. We need to create Wrapper class and need to show that wrapper class with pagination on Visual force page.
Solution :-
So If we use the StandardSetController, the check-boxes don’t maintain state if you check one and then go to the next page. To solve this problem I have implemented custom Iterator.
Even in StandardSetController constructor we cant sent List of Wrapper.
Even in StandardSetController constructor we cant sent List of Wrapper.
http://amitblog-developer-edition.ap1.force.com/apex/CustomPaginationDemo
Step 1:- Create Wrapper Class :-
global class ContactWrapper { public Boolean isSelected {get;set;} public Contact cont{get;set;} public ContactWrapper(Contact cont,Boolean isSelected) { this.cont= cont; this.isSelected= isSelected; } }
Step 2:- Create A Custom Iterator class which should implement Iterator class
global class CustomIterable implements Iterator<list<ContactWrapper>> { list<ContactWrapper> InnerList{get; set;} list<ContactWrapper> ListRequested{get; set;} Integer i {get; set;} public Integer setPageSize {get; set;} public CustomIterable(List<ContactWrapper> lstAccWr) { InnerList = new list<ContactWrapper >(); ListRequested = new list<ContactWrapper >(); InnerList = lstAccWr; setPageSize = 10; i = 0; } global boolean hasNext(){ if(i >= InnerList.size()) { return false; } else { return true; } } global boolean hasPrevious(){ system.debug('I am in hasPrevious' + i); if(i <= setPageSize) { return false; } else { return true; } } global list<ContactWrapper > next(){ system.debug('i value is ' + i); ListRequested = new list<ContactWrapper >(); integer startNumber; integer size = InnerList.size(); if(hasNext()) { if(size <= (i + setPageSize)) { startNumber = i; i = size; } else { i = (i + setPageSize); startNumber = (i - setPageSize); } system.debug('i value is =====' + i); system.debug('i value is 2==== ' + (i - setPageSize)); for(integer start = startNumber; start < i; start++) { ListRequested.add(InnerList[start]); } } return ListRequested; } global list<ContactWrapper > previous(){ ListRequested = new list<ContactWrapper >(); system.debug('i value is previous before =====' + i); integer size = InnerList.size(); if(i == size) { if(math.mod(size, setPageSize) > 0) { i = size - math.mod(size, setPageSize); } else { i = (size - setPageSize); } } else { i = (i - setPageSize); } system.debug('i value is previous =====' + i); system.debug('i value is 2previous ==== ' + (i - setPageSize)); for(integer start = (i - setPageSize); start < i; ++start) { ListRequested.add(InnerList[start]); } return ListRequested; } }
Step 3:- Create controller class :-
public with sharing class CustomPaginationDemo
{ public List<ContactWrapper> lstWrapper {get;set;} public List<ContactWrapper> lstSetController{get;set;} CustomIterable obj; public CustomPaginationDemo() { lstWrapper = new List<ContactWrapper>(); lstSetController = new List<ContactWrapper>(); List<Contact> lstContact = [select id,name from Contact limit 20]; for(Contact cont : lstContact ) { lstWrapper.add(new ContactWrapper(cont ,false)); } obj = new CustomIterable (lstWrapper); obj.setPageSize = 5; next(); } public Boolean hasNext { get { return obj.hasNext(); } set; } public Boolean hasPrevious { get { return obj.hasPrevious(); } set; } public void next() { lstSetController = obj.next(); } public void previous() { lstSetController = obj.previous(); } }
Step 4:- Create Visual Force Page :-
<apex:page controller="CustomPaginationDemo">
<apex:form > <apex:pageBlock id="ThePage"> <apex:pageBlockSection columns="1"> <apex:pageBlockTable value="{!lstSetController }" var="obj" > <apex:column headerValue="Select"> <apex:inputCheckbox value="{!obj.isSelected}"/> </apex:column> <apex:column value="{!obj.cont.Name}" headerValue="Name"/> </apex:pageBlockTable> <apex:outputPanel > <apex:commandButton value="<<Previous" action="{!previous}" rendered="{!hasPrevious}" reRender="ThePage" /> <apex:commandButton value="Next >>" action="{!next}" rendered="{!hasNext}" reRender="ThePage" /> </apex:outputPanel> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>
Standardsetcontroller Reference:- https://www.salesforce.com/us/developer/docs/pages/Content/apex_pages_standardsetcontroller.htm
https://www.salesforce.com/us/developer/docs/pages/Content/apex_ApexPages_StandardSetController_constructors.htm
Standardsetcontroller Eaxmple :-
http://blog.jeffdouglas.com/2009/07/14/visualforce-page-with-pagination/
Iterable Class Detail:-
https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_iterable.htm
Thanks
Amit Chaudhary
Hi Amit,
ReplyDeleteNice post. But I am wondering, if it is possible to add 2 more methods "First" and "Last" Buttons/links to the page.
Nice solution Amit
ReplyDeleteNice Post
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteNice Post.
ReplyDeleteCheck below methods to show First and Last
public void First()
{
while(getHasPrevious())
if(iterator != null && getHasPrevious())
listSetWrapperAccounts = iterator.previous();
else
break;
}
public void Last()
{
while(getHasNext())
if(iterator != null && getHasNext())
listSetWrapperAccounts = iterator.next();
else
break;
}
Thanks Prachi
DeleteI implemented the above same example, my pagination is working..but state is not getting retained.
ReplyDeleteSame Code is working fine and even you can check same on below demo
Deletehttp://amitblog-developer-edition.ap1.force.com/apex/CustomPaginationDemo
Please feel free to connect with me on my email id "amit.salesforce21@gmail.com"
Hi Amit. Can you please provide the test class for the above code which includes pagination from a wrapper class.Thanks!
ReplyDeleteHi Amit,
ReplyDeleteCan we somehow combine this with QueryLocator while querying ? Actually I want to persist the checkbox values while pagination but I have large number of records... few thousands
Hi Amit,
ReplyDeleteCan we somehow combine this with QueryLocator while querying ? Actually I want to persist the checkbox values while pagination but I have large number of records... few thousands
This comment has been removed by the author.
DeletePrakash - For larger count of records, why don't you use transient variable, that will avoid view state issues and Amit's code is good to maintain your selections throughout your pagination.
Deletewhat is the maximum number of records you tried with?
ReplyDeleteI don't remember the count of records but definitely it was not more than 10,000 as I had the request to save those records as well. With salesforce limit of not saving more than 10K records, I had a hard limit on that.
DeleteHi Amit,
ReplyDeleteI AM getting constructor not defined error , while im implementing customiterable obj in controller class
hello
ReplyDeletethank you for this content