Tag Archives: Pagination

Pagination In Lightning Component

Apex Class:

public class ContactAuraController {
    @AuraEnabled
    public static ContactDataTableWrapper getContactData(Decimal pageNumber, Decimal pageSize) {
        
        Integer pSize = (Integer)pageSize;
        Integer pNumber = (Integer)pageNumber;
        
        //Offset for SOQL
        Integer offset = (pNumber - 1) * pSize;
        
        //Total Records
        Integer totalRecords = [SELECT COUNT() FROM Contact];
        Integer recordEnd = pSize * pNumber;

        //Instance of Contact DataTable Wrapper Class
        ContactDataTableWrapper objDT =  new ContactDataTableWrapper();  
        objDT.pageSize = pSize;
        objDT.pageNumber = pNumber;
        objDT.recordStart = offset + 1;
        objDT.recordEnd = totalRecords >= recordEnd ? recordEnd : totalRecords;
        objDT.totalRecords = totalRecords;
        objDT.contactList = [SELECT Id, Name, Phone, Email FROM Contact ORDER BY Name LIMIT :pSize OFFSET :offset];
        return objDT;
    }
    
    //Wrapper Class For Contact DataTable  
    public class ContactDataTableWrapper {
        @AuraEnabled
        public Integer pageSize {get;set;}
        @AuraEnabled
        public Integer pageNumber {get;set;}
        @AuraEnabled
        public Integer totalRecords {get;set;}
        @AuraEnabled
        public Integer recordStart {get;set;}
        @AuraEnabled
        public Integer recordEnd {get;set;}
        @AuraEnabled
        public List<Contact> contactList {get;set;}
    }
}

Pagination Component:

<!--Pagination.cmp-->
<aura:component controller="ContactAuraController">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    
    <aura:attribute name="ContactList" type="Contact[]"/>
    <aura:attribute name="PageNumber" type="integer" default="1"/>
    <aura:attribute name="TotalPages" type="integer" default="0"/>
    <aura:attribute name="TotalRecords" type="integer" default="0"/>
    <aura:attribute name="RecordStart" type="integer" default="0"/>
    <aura:attribute name="RecordEnd" type="integer" default="0"/>
    
    <div class="slds-m-around_xx-large">
        <h1 class="slds-text-heading--medium">Contacts</h1>
        <br/>
        <div class="slds-float_right">
            <ui:inputSelect aura:id="pageSize" label="Display Records Per Page: " change="{!c.onSelectChange}">
                <ui:inputSelectOption text="10" label="10" value="true"/>
                <ui:inputSelectOption text="15" label="15"/>
                <ui:inputSelectOption text="20" label="20"/>
            </ui:inputSelect>
            <br/>
        </div>
        
        <table class="slds-table slds-table_bordered slds-table_cell-buffer">
            <thead>
                <tr class="slds-text-title_caps">
                    <th scope="col">
                        <strong><div class="slds-truncate" title="Name">Name</div></strong>
                    </th>
                    <th scope="col">
                        <strong><div class="slds-truncate" title="Phone">Phone</div></strong>
                    </th>
                    <th scope="col">
                        <strong><div class="slds-truncate" title="Email">Email</div></strong>
                    </th>
                </tr>
            </thead>
            <tbody>
                <aura:iteration items="{!v.ContactList}" var="con"> 
                    <tr>
                        <th scope="row" data-label="Name">
                            <div class="slds-truncate" title="{!con.Name}">{!con.Name}</div>
                        </th>
                        <th scope="row" data-label="Phone">
                            <div class="slds-truncate" title="{!con.Phone}">{!con.Phone}</div>
                        </th>
                        <th scope="row" data-label="Email">
                            <div class="slds-truncate" title="{!con.Email}">{!con.Email}</div>
                        </th>
                    </tr>
                </aura:iteration>	
            </tbody>
        </table>
        
        <div class="slds-clearfix">
            <div class="slds-page-header" role="banner">
                <div class="slds-float_right">            
                    <lightning:button disabled="{!v.PageNumber == 1}" variant="brand" aura:id="prevPage" label="Prev" onclick="{!c.handlePrev}" />            
                    <lightning:button disabled="{!v.PageNumber == v.TotalPages}" aura:id="nextPage" variant="brand" label="Next" onclick="{!c.handleNext}"/>
                </div>
                <p class="slds-page-header__title">{!v.RecordStart}-{!v.RecordEnd} of {!v.TotalRecords} | Page {!v.PageNumber} of {!v.TotalPages}</p>
            </div>
        </div>
    </div>
</aura:component>

Pagination JavaScript Controller:

({
    doInit: function(component, event, helper) {
        var pageNumber = component.get("v.PageNumber");  
        var pageSize = component.find("pageSize").get("v.value"); 
        helper.getContactList(component, pageNumber, pageSize);
    },
    
    handleNext: function(component, event, helper) {
        var pageNumber = component.get("v.PageNumber");  
        var pageSize = component.find("pageSize").get("v.value");
        pageNumber++;
        helper.getContactList(component, pageNumber, pageSize);
    },
    
    handlePrev: function(component, event, helper) {
        var pageNumber = component.get("v.PageNumber");  
        var pageSize = component.find("pageSize").get("v.value");
        pageNumber--;
        helper.getContactList(component, pageNumber, pageSize);
    },
    
    onSelectChange: function(component, event, helper) {
        var page = 1
        var pageSize = component.find("pageSize").get("v.value");
        helper.getContactList(component, page, pageSize);
    },
})

Pagination JavaScript Controller Helper:

({
    getContactList: function(component, pageNumber, pageSize) {
        var action = component.get("c.getContactData");
        action.setParams({
            "pageNumber": pageNumber,
            "pageSize": pageSize
        });
        action.setCallback(this, function(result) {
            var state = result.getState();
            if (component.isValid() && state === "SUCCESS"){
                var resultData = result.getReturnValue();
                component.set("v.ContactList", resultData.contactList);
                component.set("v.PageNumber", resultData.pageNumber);
                component.set("v.TotalRecords", resultData.totalRecords);
                component.set("v.RecordStart", resultData.recordStart);
                component.set("v.RecordEnd", resultData.recordEnd);
                component.set("v.TotalPages", Math.ceil(resultData.totalRecords / pageSize));
            }
        });
        $A.enqueueAction(action);
    }
})

Output:

Lightning Component Client Side Pagination

Pagination Component:
Create a new Lightning Component Pagination.cmp.

<!--Pagination.cmp-->
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" 
                controller='PaginationController'
                access="global" >
    
    <!-- Attribute Declration For Pagination -->
    <aura:attribute name="ContactData" type="Object"/>
    <aura:attribute name="columns" type="List"/>
    
    <aura:attribute name="isSending" type="boolean" />
    
    <!-- Attribute Declration For Pagination -->
    <aura:attribute name="PaginationList" type="Contact"/>
    <aura:attribute name="startPage" type="Integer" />
    <aura:attribute name="endPage" type="Integer"/>
    <aura:attribute name="totalRecords" type="Integer"/>
    <aura:attribute name="pageSize" type="Integer" default="10"/>
    <!-- Attribute Declration For Pagination End-->
    
    <aura:handler name="init" value="{! this }" action="{! c.doInit }"/>
    
    <!-- Spinner Start, show the loading screen while 
   Client side controller(JS) is communicating with Server Side(APEX) controller -->
    <aura:if isTrue="{!v.isSending}">
        <div class="slds-spinner_container">
            <div class="slds-spinner--brand slds-spinner slds-spinner--large" role="alert">
                <span class="slds-assistive-text">Loading</span>
                <div class="slds-spinner__dot-a"></div>
                <div class="slds-spinner__dot-b"></div>
            </div>
        </div>
    </aura:if>
    <!-- Spinner End -->
    
    <div class="slds-page-header">
        <div class="slds-media">
            <div class="slds-media__figure">
                <span class="slds-icon_container slds-icon-standard-opportunity" 
                      title="Description of icon when needed">
                    
                </span>
            </div>
        </div>
    </div>
    
    <div class="slds-m-top_medium" >
        <lightning:datatable data="{! v.PaginationList }" class="slds-m-top_medium"
                             columns="{! v.columns }" 
                             keyField="id"
                             onrowselection="{! c.getSelectedName }"/>	
        <br/>
        <lightning:buttonGroup >
            <lightning:button label="Previous" disabled="{!v.startPage == 0}"  
                              onclick="{!c.previous}" variant="brand"
                              iconName='utility:back'/>
            &nbsp; &nbsp; &nbsp;
            <lightning:button label="Next" disabled="{!v.endPage >= v.totalRecords}" 
                              onclick="{!c.next}" variant="brand"
                              iconName='utility:forward' iconPosition='right'/>
        </lightning:buttonGroup>
    </div>
</aura:component>

Pagination JavaScript Controller:
Now create below JavaScript PaginationController.js controller for above Pagination.cmp component.

({
    doInit: function (component, event, helper) {
        // Set the columns of the Table 
        component.set('v.isSending',true);
        component.set('v.columns', [
            {label: 'Name', fieldName: 'Name', type: 'text', sortable : true},
            {label: 'Email', fieldName: 'Email', type: 'email', sortable : true},
            {label: 'Phone', fieldName: 'Phone', type: 'phone', sortable : true}]);
        helper.doFetchContact(component);
    },
    getSelectedName: function (component, event) {
        var selectedRows = event.getParam('selectedRows');
        // Display that fieldName of the selected rows
        for (var i = 0; i < selectedRows.length; i++){
            alert("You selected: " + selectedRows[i].Name);
        }
    },
    next: function (component, event, helper) {
        helper.next(component, event);
    },
    previous: function (component, event, helper) {
        helper.previous(component, event);
    }
})

Pagination JavaScript Controller Helper:
Now create below JavaScript PaginationHelper.js helper for above PaginationController.js component.

({
    /*
     * Initially this Method will be called and will fetch the records from the Salesforce Org 
     * Then we will hold all the records into the attribute of Lightning Component
     */
    doFetchContact : function(component) {
        var action = component.get('c.getContacts');
        action.setCallback(this, function(response){
            var state = response.getState();
            if(state === 'SUCCESS' && component.isValid()){
                var pageSize = component.get("v.pageSize");
                // hold all the records into an attribute named "ContactData"
                component.set('v.ContactData', response.getReturnValue());
                // get size of all the records and then hold into an attribute "totalRecords"
                component.set("v.totalRecords", component.get("v.ContactData").length);
                // set star as 0
                component.set("v.startPage",0);
                
                component.set("v.endPage",pageSize-1);
                var PaginationList = [];
                for(var i=0; i< pageSize; i++){
                    if(component.get("v.ContactData").length> i)
                        PaginationList.push(response.getReturnValue()[i]);    
                }
                component.set('v.PaginationList', PaginationList);
                component.set('v.isSending',false);
            }else{
                alert('ERROR');
            }
        });
        $A.enqueueAction(action);
    },
    /*
     * Method will be called when use clicks on next button and performs the 
     * calculation to show the next set of records
     */
    next : function(component, event){
        var sObjectList = component.get("v.ContactData");
        var end = component.get("v.endPage");
        var start = component.get("v.startPage");
        var pageSize = component.get("v.pageSize");
        var Paginationlist = [];
        var counter = 0;
        for(var i=end+1; i<end+pageSize+1; i++){
            if(sObjectList.length > i){
                Paginationlist.push(sObjectList[i]);
            }
            counter ++ ;
        }
        start = start + counter;
        end = end + counter;
        component.set("v.startPage",start);
        component.set("v.endPage",end);
        component.set('v.PaginationList', Paginationlist);
    },
    /*
     * Method will be called when use clicks on previous button and performs the 
     * calculation to show the previous set of records
     */
    previous : function(component, event){
        var sObjectList = component.get("v.ContactData");
        var end = component.get("v.endPage");
        var start = component.get("v.startPage");
        var pageSize = component.get("v.pageSize");
        var Paginationlist = [];
        var counter = 0;
        for(var i= start-pageSize; i < start ; i++){
            if(i > -1){
                Paginationlist.push(sObjectList[i]);
                counter ++;
            }else{
                start++;
            }
        }
        start = start - counter;
        end = end - counter;
        component.set("v.startPage",start);
        component.set("v.endPage",end);
        component.set('v.PaginationList', Paginationlist);
    }
})

Pagination Apex Controller:
Create below apex controller to use it in Pagination.cmp component.

public class PaginationController {
    @AuraEnabled
    public static List<Contact> getContacts(){
        List<Contact> contactList = new List<Contact>();
        contactList = [SELECT Id, Name, Email, Phone From Contact LIMIT 50];
        return contactList;
    }
}

Pagination App:

<!--PaginationApp.app-->
<aura:application extends="force:slds">
    <c:Pagination />    
</aura:application>

Output:

Standard List Controller in Visuaforce Page

Standard List controllers allow you to create Visualforce pages that can display or act on a set of records. We can access Standard List controller with the help of recordSetVar which is the attribute of apex:page component.

Note: When you use the standardController attribute on the tag, you can’t use the controller attribute at the same time.

Standard List Controller Actions:

Action Description
apex:commandButton This tag is used to create a button
apex:commandLink This tag is used to create a link.
apex:actionSupport This tag is used to make an event such as onclick and onmouseover.
apex:actionPoller It periodically calls an action.
apex:actionFunction It defines a new JavaScript function.
apex:page Calls an action when the page is loaded.

Standard List Controller Actions Methods:

Method Decription
save Inserts new records or updates existing records that have been changed. After this operation is finished, the save action returns the user to the original page, if known, or the home page.
quicksave Inserts new records or updates existing records that have been changed. Unlike the save action, quicksave does not redirect the user to another page.
list Returns a PageReference object of the standard list page, based on the most recently used list filter for that object when the filterId is not specified by the user.
cancel Aborts an edit operation. After this operation is finished, the cancel action returns the user to the page where the user originally invoked the edit.
first Displays the first page of records in the set.
last Displays the last page of records in the set.
next Displays the next page of records in the set.
previous Displays the previous page of records in the set.

Here in below example, Visualforce Page is using the standard Controller “Contact”, and recordSetVar is set to “accounts”.

<apex:page standardController="Contact" recordSetVar="contacts" tabStyle="Contact" sidebar="false">
    <apex:form>
        <apex:pageBlock title="Contacts List" id="pbConList">
            Filter:
            <apex:selectList value="{!filterId }" size="1">
                <apex:selectOptions value="{!listViewOptions}"/>
                <apex:actionSupport event="onchange" reRender="pbConList"/>
            </apex:selectList>
            
            <!-- Contacts List -->
            <apex:pageBlockTable value="{!contacts}" var="c" rows="5">
                <apex:column value="{!c.FirstName}"/>
                <apex:column value="{!c.LastName}"/>
                <apex:column value="{!c.Email}"/>
                <apex:column value="{!c.Phone}"/>
            </apex:pageBlockTable>
            
            <!-- Pagination -->
            
<table style="width: 100%">
                
<tr>
                    
<td>
                        Page: <apex:outputText value=" {!PageNumber} of {!CEILING(ResultSize / PageSize)}"/>
                    </td>

            
                    
                    
<td align="center">
                        <!-- Previous page -->
                        <!-- active -->
                        <apex:commandLink action="{!Previous}" value="Prev" rendered="{!HasPrevious}"/>
                        <!-- inactive (no earlier pages) -->
                        <apex:outputText style="color: #ccc;" value="Prev" rendered="{!NOT(HasPrevious)}"/>
                        &nbsp;&nbsp;
                        <!-- Next page -->
                        <!-- active -->
                        <apex:commandLink action="{!Next}" value="Next" rendered="{!HasNext}"/>
                        <!-- inactive (no more pages) -->
                        <apex:outputText style="color: #ccc;" value="Next" rendered="{!NOT(HasNext)}"/>
                    </td>

                    
                    
<td align="right">
                        Records per page:
                        <apex:selectList value="{!PageSize}" size="1">
                            <apex:selectOption itemValue="5" itemLabel="5"/>
                            <apex:selectOption itemValue="20" itemLabel="20"/>
                            <apex:actionSupport event="onchange" reRender="pbConList"/>
                        </apex:selectList>
                    </td>

                </tr>

            </table>

        </apex:pageBlock>
    </apex:form>
</apex:page>

Output: