Creating Pagination Functionality Using lightning DataTable in Salesforce Lightning Web Components


In Salesforce, LWC is frequently employed to retrieve substantial data volumes from the Salesforce server and display them on the screen using either the base lightning-datatable or a customized HTML table.

In this tutorial, you’ll discover how to establish a custom JavaScript pagination mechanism using the lightning data table component to paginate extensive datasets. The example involves creating a paginated display of standard contact records in Salesforce. Additionally, users can modify the page size (number of records per page) with predefined options, such as 5, 10, 15, and more.

Output of Salesforce LWC Datable-Table Pagination Example

Following is the result of creating pagination for lightning data table in salesforce using lwc applications.

Lightning Web Component /Apex Controller – Source Code

Apex Controller – ContactDataController.cls

public with sharing class ContactDataController { 
    // apex method to fetch contact records from salesforce database 
    @AuraEnabled
    public static list<Contact> fetchContacts(){        
            list<Contact> lstContact = new list<Contact>();
            for(Contact con : [SELECT id,name,email,phone,title FROM Contact LIMIT 5000]){
                lstContact.add(con);
            } 
            return lstContact;        
    }
    
}

Html File- dataTableWithPagination.html

<template>
    <template if:true={records}>
        <!--LIGHTNING DATATABLE-->
        <div style="height:400px">
            <lightning-datatable key-field="Id" data={recordsToDisplay} hide-checkbox-column="true" columns={columns}></lightning-datatable>
        </div>
        <div class="slds-grid slds-grid_vertical-align-center slds-grid_align-spread" style="padding-top: 0.5em;">
            <!--RECORDS PER PAGE-->
            <div class="slds-col">
                <div class="slds-list_inline slds-p-bottom_xx-small">
                    <label class="slds-text-color_weak slds-p-horizontal_x-small" for="recordsPerPage">Page Size:</label>
                    <div class="slds-select_container">
                        <select class="slds-select" id="recordsPerPage" onchange={handleRecordsPerPage}>
                            <template for:each={pageSizeOptions} for:item="option">
                                <option key={option} value={option}>{option}</option>
                            </template>
                        </select>
                    </div>
                </div>
            </div>
            <!--PAGE NAVIGATION-->
            <div class="slds-align_absolute-center" style="height:5rem">
                <lightning-button disabled={bDisableFirst} icon-name="utility:jump_to_left" label="First" class="slds-p-horizontal_x-small" alternative-text="first page" onclick={firstPage}></lightning-button>
                <lightning-button disabled={bDisableFirst} icon-name="utility:chevronleft" label="Previous" alternative-text="Previous" onclick={previousPage}></lightning-button>
                &nbsp;
                <span class="slds-badge">Showing {pageNumber} &nbsp;of&nbsp; {totalPages} &nbsp;&nbsp;Page(s)</span>
                &nbsp;
                <lightning-button disabled={bDisableLast} icon-name="utility:chevronright" label="Next" alternative-text="Next" onclick={nextPage} class="slds-p-horizontal_x-small" icon-position="right"></lightning-button>
                <lightning-button disabled={bDisableLast} icon-name="utility:jump_to_right" label="Last" alternative-text="last page" onclick={lastPage} icon-position="right"></lightning-button>
            </div>
            <!--TOTAL RECORDS-->
            <div class="slds-clearfix">
                <div class="slds-float_right">
                    <span class="slds-badge"> Total Records: {totalRecords}</span>
                </div>
            </div>
        </div>
    </template>
</template>

JavaScript File – dataTableWithPagination.js

/*
API : 52
Source : lwcFactory.com
*/
import {LightningElement} from 'lwc';
//Import apex method 
import fetchContacts from '@salesforce/apex/.fetchContacts';
export default class DatatableWithPagination extends LightningElement {
    
    // JS Properties 
    pageSizeOptions = [5, 10, 25, 50, 75, 100]; //Page size options
    records = []; //All records available in the data table
    columns = []; //columns information available in the data table
    totalRecords = 0; //Total no.of records
    pageSize; //No.of records to be displayed per page
    totalPages; //Total no.of pages
    pageNumber = 1; //Page number    
    recordsToDisplay = []; //Records to be displayed on the page
    
    get bDisableFirst() {
        return this.pageNumber == 1;
    }
    get bDisableLast() {
        return this.pageNumber == this.totalPages;
    }
    // connectedCallback method called when the element is inserted into a document
    connectedCallback() {
        // set datatable columns info
        this.columns = [{
                label: 'Name',
                fieldName: 'Name'
            },
            {
                label: 'Email',
                fieldName: 'Email'
            },
            {
                label: 'Phone',
                fieldName: 'Phone'
            },
            {
                label: 'Title',
                fieldName: 'Title'
            },
        ];
        // fetch contact records from apex method 
        fetchContacts()
            .then((result) => {
                if (result != null) {
                    console.log('RESULT--> ' + JSON.stringify(result));
                    this.records = result;
                    this.totalRecords = result.length; // update total records count                 
                    this.pageSize = this.pageSizeOptions[0]; //set pageSize with default value as first option
                    this.paginationHelper(); // call helper menthod to update pagination logic 
                }
            })
            .catch((error) => {
                console.log('error while fetch contacts--> ' + JSON.stringify(error));
            });
    }
    handleRecordsPerPage(event) {
        this.pageSize = event.target.value;
        this.paginationHelper();
    }
    previousPage() {
        this.pageNumber = this.pageNumber - 1;
        this.paginationHelper();
    }
    nextPage() {
        this.pageNumber = this.pageNumber + 1;
        this.paginationHelper();
    }
    firstPage() {
        this.pageNumber = 1;
        this.paginationHelper();
    }
    lastPage() {
        this.pageNumber = this.totalPages;
        this.paginationHelper();
    }
    // JS function to handel pagination logic 
    paginationHelper() {
        this.recordsToDisplay = [];
        // calculate total pages
        this.totalPages = Math.ceil(this.totalRecords / this.pageSize);
        // set page number 
        if (this.pageNumber <= 1) {
            this.pageNumber = 1;
        } else if (this.pageNumber >= this.totalPages) {
            this.pageNumber = this.totalPages;
        }
        // set records to display on current page 
        for (let i = (this.pageNumber - 1) * this.pageSize; i < this.pageNumber * this.pageSize; i++) {
            if (i === this.totalRecords) {
                break;
            }
            this.recordsToDisplay.push(this.records[i]);
        }
    }
}

Meta xml file – dataTableWithPagination.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__HomePage</target>
        <target>lightning__Tab</target>
    </targets>    
</LightningComponentBundle>

Explanation:

The “pageNumber” is initialized with a value of 1, signifying that when the Lightning Web Component (LWC) is loaded, it will exhibit the first page as the current page. The number of items per page is determined by the “pageSize” JavaScript property, which is set to the first index item [5] of the ‘pageSizeOptions’ list.

The “totalRecords” JavaScript property indicates the total number of records returned from the Apex controller. The “recordsToDisplay” array property is utilized to filter and store the records for the current page when pagination changes. The “pageSizeOptions” property contains predefined options for the page size drop-down, and you can adjust the default values according to your requirements.

Within the JavaScript file, a common “paginationHelper()” function is implemented. This function calculates the paginated records for the current page based on the total number of pages and the current page number in context.