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.
