Pagination with Page Number in Lightning Component

By | November 11, 2019

Hi, In this scenario we have shown, how to display pagination in Lightning Component. Pagination will be in numbers display format…

Apex Controller

public with sharing class Pagination {
    /* Account pagination query to query record with OFFSET and LIMIT */    
    @AuraEnabled
    public static List<Account> getAllRecords(String pageNumber,String currnetPagesCount){
        String accountQuery = 'SELECT Id,Name,Type,Industry,Rating,BillingCity FROM Account ORDER BY Name LIMIT '+currnetPagesCount+' OFFSET ';
        if(String.isBlank(pageNumber) || Integer.valueOf(pageNumber) == 1){
            accountQuery = accountQuery + ' 0';
        }else{
            accountQuery = accountQuery + String.valueOf((Integer.valueOf(pageNumber)-1)*Integer.valueOf(currnetPagesCount));
        }
        return Database.query(accountQuery);
    }
    
    /* When total number of records to display changes provide 
       footer with new set of page counter info to display */
    
    @AuraEnabled
    public static PageInfo getPageCountInfo(String pageCountInfo){
        
        Integer currentListCount = pageCountInfo != null && pageCountInfo != '' ? Integer.valueOf(pageCountInfo) : 5;
        
        PageInfo pgn = new PageInfo();        
        pgn.totalPages = ([SELECT COUNT() FROM Account]/(currentListCount))+1;
        pgn.currentPageNumber = 1;
        List<Integer> cnt = new List<Integer>();
        for(Integer loop_var = 0;loop_var < pgn.totalPages;loop_var++){
            cnt.add(loop_var+1);
            if((loop_var+1) == 4)
                break;
        }
        if(pgn.totalPages > 4)
            cnt.add(pgn.totalPages);
        pgn.pageCounter = cnt;
        
        return pgn;        
    }
    
    /*When page count change or next or previous button is clicked
      provide footer with new set of page counter info to display */
    
    @AuraEnabled
    public static PageInfo getPageCountChange(String pageNumber,String currnetPagesCount,String totalPages){
        PageInfo pgn = new PageInfo();
        pgn.currentPageNumber = Integer.valueOf(pageNumber);
        pgn.totalPages = Integer.valueOf(totalPages);
        
        List<Integer> cnt = new List<Integer>();
        
        if((Integer.valueOf(pageNumber)+2) < Integer.valueOf(totalPages) && Integer.valueOf(pageNumber) != 1){
            for(Integer loop_var = (Integer.valueOf(pageNumber)-1);loop_var < (Integer.valueOf(pageNumber)+3);loop_var++){
                cnt.add(loop_var);
            }
            cnt.add(pgn.totalPages);
            
        }else if(Integer.valueOf(pageNumber) == 1){
            for(Integer loop_var = 1;loop_var < 5;loop_var++){
                cnt.add(loop_var);
            }
            cnt.add(pgn.totalPages);
        }else{
            if(Integer.valueOf(currnetPagesCount) >= pgn.totalPages){
                for(Integer loop_var = 1;loop_var < (pgn.totalPages+1);loop_var++){
                    cnt.add(loop_var);
                }
            }else{
                for(Integer loop_var = (pgn.totalPages-4);loop_var < (pgn.totalPages+1);loop_var++){
                    cnt.add(loop_var);
                }
            }
        }
        pgn.pageCounter = cnt;
        
        return pgn;
    }
    public class PageInfo {
        @AuraEnabled
        public Integer currentPageNumber {get;set;}
        
        @AuraEnabled
        public Integer totalPages {get;set;}
        
        @AuraEnabled
        public List<Integer> pageCounter {get;set;}
        
    }
    
}

Lightning Event : pageChangeEvt.evt

This Event is to handle page change in Pagination app, It takes page number and current number of records to display as parameters

<aura:event type="APPLICATION" description="Event template" >
    <!-- Event to handle page change in Pagination app
         It take page number and current number of records
         to display as parameters -->
    <aura:attribute name="pageNumber" type="String"/>
    <aura:attribute name="currnetPagesCount" type="String"/>
</aura:event>

Lightning Event : pageTotalChange.evt

This Event is to handle number of records change in Pagination app.

<aura:event type="APPLICATION" description="Event template" >
    <!--Event to handle number of records change in Pagination app -->
    <aura:attribute name="currnetPagesCount" type="String"/>
</aura:event>

Lightning Component : Pagination1

<aura:component controller="Pagination" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <aura:attribute name="pageNumber" type="String" default="1" />
    <aura:attribute name="currentPagesCount" type="String" default="5" />
    <aura:attribute name="accounts" type="Account[]" />
    
    <!-- Handler for the page chage event -->
    <aura:handler event="c:PageChangeEvt" action="{!c.pageChange}" />
    <!-- Handler for the total records to display event -->
    <aura:handler event="c:PageTotalChange" action="{!c.recordCounterChange}" />
    
    <!-- Registering event which will fire when the number of records to display will change
         This event will be handled by the Table and Footer component to adjust the change -->
    <aura:registerEvent name="pagesCountChange" type="c:PageTotalChange"  />
    
    <!-- This component will display page number it is a single count display
         iterated over total pages counts currenty it wil show max 5 page number count
         with first 4 in sequence and last on as last page number  -->
    <aura:attribute name="pageNumber1" type="String"/>
    <aura:attribute name="currentPageNumber" type="String"/>
    <aura:attribute name="currnetPagesCount" type="String"/>
    <aura:registerEvent name="goToPage" type="c:PageChangeEvt"/>     
    
    <header class="slds-global-header_container">
        <div class="slds-global-header slds-grid slds-grid_align-spread">
            <div class="slds-global-header__item">
                <legend class="slds-form-element__label slds-text-title_caps">Pagination</legend>
            </div>            
            
            <div class="slds-global-header__item" style="width:12%;">
                <div class="slds-form slds-form_horizontal">
                    <lightning:select name="selectItem" aura:id="selectItem" label="Records" variant="label-hidden" onchange="{!c.changeRecordNumber}">
                        <option value="5">5</option>
                        <option value="10">10</option>
                        <option value="25">25</option>
                    </lightning:select>
                </div>
            </div>            
        </div>
    </header>    
    
    <table class="slds-table slds-table--bordered slds-table--cell-buffer" style="margin-top:50px;">
        <thead>
            <tr class="slds-text-heading--label">
                <th scope="col">
                    <div class="slds-truncate" title="Account Name">Account Name</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Account Type">Account Type</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Industry">Industry</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="City">City</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Rating">Rating</div>
                </th>
            </tr>
        </thead>
        <tbody>
            <aura:iteration items="{!v.accounts}" var="acc">
                <tr>
                    <th scope="row">
                        <div class="slds-truncate" title="Account Name">{!acc.Name}</div>
                    </th>
                    <th scope="row">
                        <div class="slds-truncate" title="Account Type">{!acc.Type}</div>
                    </th>
                    <th scope="row">
                        <div class="slds-truncate" title="Industry">{!acc.Industry}</div>
                    </th>
                    <th scope="row">
                        <div class="slds-truncate" title="City">{!acc.BillingCity}</div>
                    </th>
                    <th scope="row">
                        <div class="slds-truncate" title="Rating">{!acc.Rating}</div>
                    </th>
                </tr>
            </aura:iteration>
        </tbody>        
    </table>   
</aura:component>

js Controller : Pagination1

({
    doInit: function(component,event,helper) {
        helper.getAllSobjectRecords(component, component.get("v.pageNumber"), 
                                    component.get("v.currentPagesCount"));
    },
    pageChange: function(component, event, helper) {
        var pageNumber = event.getParam("pageNumber");
        var currnetPagesCount = event.getParam("currnetPagesCount");
        
        component.set("v.pageNumber", pageNumber);
        component.set("v.currentPagesCount", currnetPagesCount);
        
        helper.getAllSobjectRecords(component, pageNumber, currnetPagesCount);
    },
    
    recordCounterChange : function(component, event, helper){
        var currnetPagesCount = event.getParam("currnetPagesCount");
        component.set("v.pageNumber", '1');
        component.set("v.currentPagesCount", currnetPagesCount);
        helper.getAllSobjectRecords(component,'1', currnetPagesCount);
    },
    
    /* Get the changed record count pass the count to the event Fire the event */
    changeRecordNumber : function(component, event, helper) {
        var currentPagesCount  = component.find("selectItem").get("v.value");
        var myEvent = $A.get("e.c:PageTotalChange");
        myEvent.setParams({ "currnetPagesCount": currentPagesCount});
        myEvent.fire();
        
    },    
})

js Helper : pagination1

({
	getAllSobjectRecords : function(component,pNum,rCunt) {
		var action = component.get("c.getAllRecords");

		action.setParams({
            "pageNumber" : pNum.toString(),
            "currnetPagesCount" : rCunt.toString()
        });
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (component.isValid() && state === "SUCCESS") {
                component.set("v.accounts", response.getReturnValue());                
            }
        });
        $A.enqueueAction(action);	
	},
   
})

Css Styles : pagination1

.THIS .LabelHeight {
    line-height:24px;
}

Lightning Component : PageCount

<aura:component controller="Pagination" >
	<!--This component will display page number it is a single count display
	    iterated over total pages counts currenty it wil show max 5 page number count
	    with first 4 in sequence and last on as last page number -->
    <aura:attribute name="pageNumber" type="String"/>
    <aura:attribute name="currentPageNumber" type="String"/>
    <aura:attribute name="currnetPagesCount" type="String"/>
    <aura:registerEvent name="goToPage" type="c:PageChangeEvt"/>
    <!-- Highlight the current page count -->
    <lightning:button variant="{!v.pageNumber == v.currentPageNumber ? 'brand' : 'neutral' }" label="{!v.pageNumber}" onclick="{!c.openthePage}" />
</aura:component>

js Controller : pagecount

This will Fire page change event with new page number and current records counts. This will be handled by Table and Footer component.

({
	/* Fire page change event with new page number and current records counts
       This will be handled by Table and Footer component */
	openthePage : function(component, event, helper) {

	    var myEvent = $A.get("e.c:PageChangeEvt");
        var pageNumber = component.get("v.pageNumber");

        myEvent.setParams({
            "pageNumber": pageNumber,
            "currnetPagesCount": component.get("v.currnetPagesCount")
        });

        myEvent.fire();
	}
})

Lightning Component : pageFooter

<aura:component controller="Pagination" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
    
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    
    <!-- Wrapper class to page pagination info like tolal pages, current page and page count sequence  -->
    <aura:attribute name="pageCounterInfo" type="Pagination" />
    
    <!-- Handler for the page chage event -->
    <aura:handler event="c:PageChangeEvt" action="{!c.pageChange}" />
    
    <!-- Handler for the total records to display event -->
    <aura:handler event="c:PageTotalChange" action="{!c.recordCounterChange}" />
    
    <aura:attribute name="currnetPagesCount" type="String" default="5" />
    
    <footer class="pageFooter">
        <div class="slds-global-header slds-grid slds-grid_align-spread">
            <div class="slds-global-header__item">
                <legend class="slds-form-element__label slds-text-title_caps">{!v.pageCounterInfo.currentPageNumber} of Total {!v.pageCounterInfo.totalPages} Pages</legend>
            </div>
            <div class="slds-button-group" role="group" style="margin-left:78%;position:fixed;">
                <!-- Previous button, it will be disabled if current page is the first page -->
                <lightning:buttonIcon iconName="utility:left" disabled="{!v.pageCounterInfo.currentPageNumber == 1}" variant="border" alternativeText="Left" iconClass="dark" onclick="{!c.goPreviousPage}" />
                
                <!-- Total of 5 page counts with last one is last page number -->
                <aura:iteration items="{!v.pageCounterInfo.pageCounter}" var="pgn">
                    <c:PageCount pageNumber="{!pgn}" currentPageNumber="{!v.pageCounterInfo.currentPageNumber}" currnetPagesCount="{!v.currnetPagesCount}" />
                </aura:iteration>
                
                <!-- Next button, it will be disabled if current page is the last page -->
                <lightning:buttonIcon iconName="utility:right" variant="border" alternativeText="Right" iconClass="dark" onclick="{!c.goNextPage}" disabled="{!v.pageCounterInfo.currentPageNumber == v.pageCounterInfo.totalPages}" />
            </div>
        </div>
    </footer>
</aura:component>

js Controller : pageFooter

({
    doInit : function(component, event, helper) {
        var rCount = '';
        helper.getPageCountAndTotal(component,rCount);
    },
    
    // Go to previous page
    goPreviousPage : function (component, event, helper) {
        var totalPages = component.get("v.pageCounterInfo.totalPages");
        var pageNumber = component.get("v.pageCounterInfo.currentPageNumber");
        var currnetPagesCount = 5;
        
        var myEvent = $A.get("e.c:PageChangeEvt");
        myEvent.setParams({
            "pageNumber": (parseInt(pageNumber)-1).toString(),
            "currnetPagesCount": currnetPagesCount.toString()
        });
        myEvent.fire();
    },
    
    // go to next page
    goNextPage : function (component, event, helper) {
        var totalPages = component.get("v.pageCounterInfo.totalPages");
        var pageNumber = component.get("v.pageCounterInfo.currentPageNumber");
        var currnetPagesCount = 5;
        
        var myEvent = $A.get("e.c:PageChangeEvt");
        myEvent.setParams({
            "pageNumber": (parseInt(pageNumber)+1).toString(),
            "currnetPagesCount": currnetPagesCount.toString()
        });
        myEvent.fire();
    },
    
    // Page count button click and page change
    pageChange: function (component, event, helper) {
        var pageNumber = event.getParam("pageNumber");
        var currnetPagesCount = event.getParam("currnetPagesCount");
        var totalPages = component.get("v.pageCounterInfo.totalPages");
        helper.resetCounters(component, pageNumber, currnetPagesCount,totalPages);
    },
    
    // Handle current record count change
    recordCounterChange : function (component, event, helper) {
        var currnetPagesCount = event.getParam("currnetPagesCount");
        component.set("v.currnetPagesCount", currnetPagesCount);
        helper.getPageCountAndTotal(component,currnetPagesCount);
    }
})

js Helper : PageFooter

({
    getPageCountAndTotal : function(component,rCount) {
        var action = component.get("c.getPageCountInfo");
        action.setParams({
            "pageCountInfo" : rCount
        });        
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (component.isValid() && state === "SUCCESS") {
                component.set("v.pageCounterInfo", response.getReturnValue());                
            }
        });
        $A.enqueueAction(action);
    },
    
    resetCounters : function (component,pNum,rCunt,totalPage) {
        var action = component.get("c.getPageCountChange");
        action.setParams({
            "pageNumber" : pNum.toString(),
            "currnetPagesCount" : rCunt.toString(),
            "totalPages" : totalPage.toString()
        });
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (component.isValid() && state === "SUCCESS") {
                console.log(response.getReturnValue());
                component.set("v.pageCounterInfo", response.getReturnValue());
            }
        });
        $A.enqueueAction(action);
    }
})

Css Styles

.THIS .pageFooter {
    position: fixed ;
    bottom: 0 ;
    z-index: 100 ;
    left: 0 ;
    width: 100% ;
}

Application

In Application we need to call 2 components Pagination1 & pageFooter.

<aura:application  extends='force:slds'>
    <c:Pagination1/>
    <c:pageFooter/> 
</aura:application>

Output

One thought on “Pagination with Page Number in Lightning Component

  1. SFDC-FOX

    Thanks for sharing this. This is the best code so far for the pagination on the lightning component.

Leave a Reply

Your email address will not be published. Required fields are marked *