Motivation
So far we know, pagination can be easily be achieved by StandardSetController class.
I have seen cases where developer has a notion like until and unless we use controller extension and StandardSetController as an argument in Constructor, pagination is difficult to achieve. For this, I have tried this approach in Custom Controller with the search input from Visualforce screen.
User will provide the input and clicking on Search button, the results will be displayed in paginated format. User can change the page size and system will fetch the records based on selected page size.
Visualforce
It will take Opportunity Name as input search criteria and clicking on Search button it will pass to the controller.
Custom Controller
It has following activities:
1. In the Constructor, assigning default page size and preparing the list of page size options.
2. showAll() - This method is getting called with Search button is clicked. In this method, searchString is getting collected and getting passed into dynamic query.
Now, main important part, this line, create QueryLocator object using Database.getQueryLocator(query) and assign that into ApexPages.StandardSetController constructor to create StandardSetController object.
Rest is easy. StandardSetController will take all burden for pagination.
3. getOpps() - This method return List of records based on pageSize.
4. refreshPageSize() - This method is getting called when paginated size is changed on screen.
Results
Hope it helps! and if so, then share with your friends.
Link to my answer in stackexchange: My Answer in Stackechange
So far we know, pagination can be easily be achieved by StandardSetController class.
I have seen cases where developer has a notion like until and unless we use controller extension and StandardSetController as an argument in Constructor, pagination is difficult to achieve. For this, I have tried this approach in Custom Controller with the search input from Visualforce screen.
Use Case
User will provide the input and clicking on Search button, the results will be displayed in paginated format. User can change the page size and system will fetch the records based on selected page size.
Solution
For the sake of learning, I have created a visualforce page as below.Visualforce
It will take Opportunity Name as input search criteria and clicking on Search button it will pass to the controller.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <apex:page id="filterPage" controller = "FilterSearch"> <apex:form style="overflow-y:auto;overflow-x:auto;margin-right: 5px;margin-left: 5px;margin-top: 3px;" id="searchForm"> <apex:actionFunction name="refreshPageSize" action="{!refreshPageSize}" status="fetchStatus" reRender="searchBlock"/> <apex:outputLabel value="Search By Opportunity Name:"/> <apex:inputText value="{!searchString}" label="Opportunity Name:"/> <apex:commandButton value="Search " action="{!showAll}"/> <apex:pageBlock title="Results" rendered="{!showResult}" id="searchBlock"> <apex:pageblockTable value="{!Opps}" var="a" id="tabId"> <apex:column> <a href="/{!a.id}" target="_blank"> {!a.name}</a> </apex:column> <apex:column rendered="false" id="id"> <apex:outputField value="{!a.id}" /> </apex:column> <apex:column headerValue="Account Name"> <apex:outputField value="{!a.account.name}" /> </apex:column> <apex:column headerValue="Stage"> <apex:outputField value="{!a.stagename}" /> </apex:column> <apex:column headerValue="Forecast Category" > <apex:outputField value="{!a.ForecastCategoryName}" /> </apex:column> </apex:pageBlockTable> <apex:panelGrid columns="8"> <apex:selectList value="{!size}" multiselect="false" size="1" onchange="refreshPageSize();"> <apex:selectOptions value="{!paginationSizeOptions}"/> </apex:selectList> <apex:commandButton status="fetchStatus" reRender="searchBlock" value="<<" action="{!setCon.first}" disabled="{!!setCon.hasPrevious}" title="First Page"/> <apex:commandButton status="fetchStatus" reRender="searchBlock" value="<" action="{!setCon.previous}" disabled="{!!setCon.hasPrevious}" title="Previous Page"/> <apex:commandButton status="fetchStatus" reRender="searchBlock" value=">" action="{!setCon.next}" disabled="{!!setCon.hasNext}" title="Next Page"/> <apex:commandButton status="fetchStatus" reRender="searchBlock" value=">>" action="{!setCon.last}" disabled="{!!setCon.hasNext}" title="Last Page"/> <apex:outputText >{!(setCon.pageNumber * size)+1-size}-{!IF((setCon.pageNumber * size)>noOfRecords, noOfRecords, (setCon.pageNumber * size))} of {!noOfRecords} </apex:outputText> <apex:outputPanel > </apex:outputPanel> </apex:panelGrid> </apex:pageBlock> </apex:form> </apex:page> |
Custom Controller
It has following activities:
1. In the Constructor, assigning default page size and preparing the list of page size options.
2. showAll() - This method is getting called with Search button is clicked. In this method, searchString is getting collected and getting passed into dynamic query.
Now, main important part, this line, create QueryLocator object using Database.getQueryLocator(query) and assign that into ApexPages.StandardSetController constructor to create StandardSetController object.
Rest is easy. StandardSetController will take all burden for pagination.
setCon = new ApexPages.StandardSetController(Database.getQueryLocator(query));
3. getOpps() - This method return List of records based on pageSize.
4. refreshPageSize() - This method is getting called when paginated size is changed on screen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | public class FilterSearch { public String searchString{get;set;} public Boolean showResult{get;set;} public Integer noOfRecords{get; set;} public Integer size{get;set;} public ApexPages.StandardSetController setCon{get;set;} public List<SelectOption> paginationSizeOptions{get;set;} String errorStr = ''; /** * FilterSearch * Constructor to initiate the default values at the time of Loading */ public FilterSearch() { size=10; //default page size //pagination size options paginationSizeOptions = new List<SelectOption>(); paginationSizeOptions.add(new SelectOption('10','10')); paginationSizeOptions.add(new SelectOption('20','20')); paginationSizeOptions.add(new SelectOption('30','30')); } public void showAll() { try { if(String.isNotBlank(searchString)) { //build SOQL query string String query='Select Id,Name, account.name, stagename, ForecastCategoryName FROM Opportunity WHERE Name LIKE \'%' + searchString + '%\' order by Name LIMIT 1000'; //return querylocator to an instance of StandardSetController setCon = new ApexPages.StandardSetController(Database.getQueryLocator(query)); if(setCon.getResultSize() >0) { showResult = true; }else{ showResult = false; ApexPages.addmessage(new ApexPages.message(ApexPages.severity.INFO,'No Records Found.')); } } }catch(Exception ex) { errorStr ='Error Occured while Searching.'; ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 'errorStr:' +ex.getMessage())); } } public List<Opportunity> getOpps() { if(setCon.getResultSize() >0) { setCon.setPageSize(size); noOfRecords = setCon.getResultSize(); return (List<Opportunity>)setCon.getRecords(); }else { return null; } return null; } /** * refreshPageSize * Changes the size of Pagination. * @param * @return void */ public void refreshPageSize() { setCon.setPageSize(size); } } |
Results
Hope it helps! and if so, then share with your friends.
Link to my answer in stackexchange: My Answer in Stackechange
Thanks for this post Shantanu. Is there any limitation in terms of number of data?
ReplyDeleteGreat work Santanu!!
ReplyDeleteThanks Mangesh.
DeleteI read your blog frequently and I just thought I’d say keep up the amazing work!
ReplyDeleteClick Here
Thanks Kandy Pulice
Delete