Custom-Pagination-in-Salesforce

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 &amp;&amp; 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.

Popular Salesforce Blogs