Salesforce Visualforce - Custom Pagination Without Using Offset in Salesforce
Hello guys,
Today, I am going to share a code that how we can build custom pagination without using Offset.
For that, I am using Visualforce and the Apex controller.
Code for Visualforce:
<apex:page showHeader="false" controller="CustomPaginationWithoutOffsetController" sidebar="false" > <apex:form> <apex:pageBlock title="Custom Pagination"> <!-- next, previous and page info --> <apex:commandLink action="{!doPrevious}" rendered="{!hasPrevious}" value="Previous" /> <apex:outputLabel rendered="{!NOT(hasPrevious)}" value="Previous" /> <apex:outputLabel value=" (page {!page} of {!totalPages}) | showing {!startIdx} to {!endIdx} of {!totalRecords} " /> <apex:commandLink action="{!doNext}" rendered="{!hasNext}" value="Next" /> <apex:outputLabel rendered="{!NOT(hasNext)}" value="Next" /> <br/> <!-- table of data --> <apex:pageBlockTable title="Accounts" value="{!tRecords}" var="a"> <apex:column value="{!a.tAccount.ID}"/> <apex:column value="{!a.tAccount.Name}"/> </apex:pageBlockTable> <br/> <!-- next, previous and page info --> <apex:commandLink action="{!doPrevious}" rendered="{!hasPrevious}" value="Previous" /> <apex:outputLabel rendered="{!NOT(hasPrevious)}" value="Previous" /> <apex:outputLabel value=" (page {!page} of {!totalPages}) | showing {!startIdx} to {!endIdx} of {!totalRecords} " /> <apex:commandLink action="{!doNext}" rendered="{!hasNext}" value="Next" /> <apex:outputLabel rendered="{!NOT(hasNext)}" value="Next" /> </apex:pageBlock> </apex:form> </apex:page>
Apex Controller Code:
public class CustomPaginationWithoutOffsetController { //default page size private static final Integer PAGE_SIZE = 10; //pagination information public Integer page{get;set;} public Integer totalRecords{get;set;} public Integer totalPages{get;set;} public Integer startIdx{get;set;} public Integer endIdx{get;set;} //set controller public List<CCWRow> tRecords{get;set;} //constructor public CustomPaginationWithoutOffsetController () { //init variable this.tRecords = new List<CCWRow>(); //set initial page this.page = 1; //load records getAccounts(); } //advance to next page public void doNext(){ if(getHasNext()){ this.page++; getAccounts(); } } //advance to the previous page public void doPrevious(){ if(getHasPrevious()){ this.page--; getAccounts(); } } //returns whether the previous page exists public Boolean getHasPrevious(){ if(this.page>1){ return true; } else{ return false; } } //returns whether the next page exists public Boolean getHasNext(){ if(this.page<this.totalPages){ return true; } else{ return false; } } //return the current page of records public void getAccounts(){ //calculate the range of records for capture this.startIdx = (this.page-1)*PAGE_SIZE; this.endIdx = this.page*PAGE_SIZE; this.totalRecords = 0; //clear container for records displayed this.tRecords.clear(); //cycle through for(Account acc : [SELECT Id, Name FROM Account ORDER BY Name ASC LIMIT 50000]){ //capture records within the target range if(this.totalRecords>=this.startIdx && this.totalRecords<this.endIdx){ this.tRecords.add( new CCWRow(acc) ); } //count the total number of records this.totalRecords++; } //calculate total pages Decimal pages = Decimal.valueOf(this.totalRecords); System.debug('@@@pages'+ pages); pages = pages.divide(Decimal.valueOf(PAGE_SIZE), 2); System.debug('@@@pages'+ pages); this.totalPages = (Integer)pages.round(System.RoundingMode.CEILING); System.debug('@@@totalpages'+ totalPages); //adjust start index e.g. 1, 11, 21, 31 this.startIdx++; //adjust end index if(this.endIdx>this.totalRecords){ this.endIdx = this.totalRecords; } //display resource usage System.Debug(LoggingLevel.WARN,'@@@ LIMIT query rows: '+Limits.getQueryRows()+' / '+Limits.getLimitQueryRows()); System.Debug(LoggingLevel.WARN,'@@@ LIMIT heap size: '+Limits.getHeapSize()+' / '+Limits.getLimitHeapSize()); System.Debug(LoggingLevel.WARN,'@@@ LIMIT cpu time: '+Limits.getCpuTime()+' / '+Limits.getLimitCpuTime()); } // helper class that represents a row public with sharing class CCWRow{ public Account tAccount{get;set;} public CCWRow(Account acc){ this.tAccount=acc; } } }
Output-
Thanks.
Happy Coding.