How to implement client side pagination in LWC ?

In this article, we are going to see how to implement client side pagination in LWC. Let say you have got requirement to get contacts from apex controller and display it in a table. But the catch here is there are 100s of records and now you have got the task to implement pagination such that you can also control how many records can be shown in the table from component only. So let's begin

1.Let's say we have got apex controller as below :
@AuraEnabled(cacheable=true)
public static List getMContact(String uId){
List cList = new List();
system.debug('The user Id is '+uId);
User ug = [Select Id,Contact.AccountId from User WHERE Id =: uId LIMIT 1];
if(ug != null){
cList = [Select Id,Name,Phone,BirthDate,Email,MobilePhone,Role__c,is_Active__c from Contact WHERE AccountId =: ug.Contact.AccountId];
}
system.debug('the count is '+cList.size());
return cList;
}




2. Now we will create an LWC component for that as shown below :
<template for:each={recordsToDisplay} for:item="contact">      
        <div  key={contact.Id} onclick={showRow} data-contact-id={contact.Id}>
            <template if:true={contact.showAdditionalData} >
            <img src={arrowUp} onclick={showRow} data-contact-id={contact.Id} />
            </template>
            <template if:false={contact.showAdditionalData}>
                <img src={arrowDown} onclick={showRow} data-contact-id={contact.Id} />
            </template>   
        <p >{contact.Name}</p>
        <a > <img src={emailLogo} />{contact.Email}</a>
        <button if:true={contact.is_Active__c} >Active</button>
        <button if:false={contact.is_Active__c} >Inactive</button>
        <p  data-contact-id={contact.Id} onclick={handleEditForm}> 
         <img  src={editLogo} />Edit</p>
        </div>




<div>
    <div ><p>Items per page : </p>
                            <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>
    <p >{pageL} - {pageU} of {totalNumberofRecords} items</p>
    <p >
            <select  class="slds-select " id="PageNumber" onchange={handlePageNumber}>
            <template  for:each={pageNumberOptions} for:item="option">
            <option  key={option} value={option} >{option}</option>
            </template>
            </select>
        of {totalPages} pages</p>
    <p  onclick={previousPage}>
     <img src={arrowUp} /></p>
    <p  onclick={nextPage}><img src={arrowDown}/></p>
    </div>
</template>  


3. Now we will look for the JS code of the component : 
  import getMContacts from '@salesforce/apex/administrationMP.getMContact';
export default class SalesPersonDatatableMP extends LightningElement {
    @api arrowUp;
    @api arrowDown;
    @api currentArrow;
    @api cData;
    @api nData;
    @api tData;
    @api error;
    @api pageL;
    @api pageU;
    @api numberOfRecords = 5;
    @api totalNumberOfRecords;
    @api totalPages;
    @api recordsDisplaying;
    @api recordsToDisplay = [];
    @api pageSizeOptions = [5, 10, 25, 50, 75, 100];
    @api pageNumberOptions = [];
    @api pageNumber;
    @api showForm = false;

      connectedCallback(){
        this.getData();
    }
     //Fetching data to be displayed from Apex
     getData(){
        getMContacts({uId : this.userId})
        .then(result =>{
            this.totalNumberofRecords = result.length;
            this.cData = result.map(contact => ({
                ...contact,
                showAdditionalData: false
            }));
           this.nData = this.cData;
           this.pageNumber = 1;
           this.totalPages = Math.ceil(this.totalNumberofRecords / this.numberOfRecords);
          this.paginationHelper();
        })
        .catch(error =>{
            console.log('The error is '+JSON.stringify(error));
        })
    }
    //This is to set the number of records to be displayed on page
    handleRecordsPerPage(event) {
        this.numberOfRecords = event.target.value;
        this.getData();
    }

    //Previous page selection
    previousPage() {
        this.pageNumber = this.pageNumber - 1;
        console.log('the pageNumber is '+this.pageNumber)
        this.paginationHelper();
       
    }

    //Next page selection
    nextPage() {
        this.pageNumber = this.pageNumber + 1;
        console.log('the pageNumber is '+this.pageNumber)
        this.paginationHelper();
    }
   

    //This method is used to set the records being displayed in case of any event such as next page, previous page etc
    paginationHelper(){
      this.recordsToDisplay = [];
      this.pageNumberOptions = [];
     
      for(let j = 1; j <= this.totalPages ; j++){
        this.pageNumberOptions.push(j);   //
      }

   
      if (this.pageNumber <= 1) {
        this.pageNumber = 1;
       } else if (this.pageNumber >= this.totalPages) {
        this.pageNumber = this.totalPages;
      }
 
     
      this.pageL = ((this.pageNumber-1) * this.numberOfRecords)+1;
      this.pageU =  this.pageNumber * this.numberOfRecords;
     

      for (let i = (this.pageNumber - 1) * this.numberOfRecords; i < this.pageNumber * this.numberOfRecords; i++) {
        if (i ===   this.totalNumberofRecords ) {
            break;
        }
        this.recordsToDisplay.push(this.cData[i]);
      }
    }


}


4. The output will look like the image below :




5. For any queries you can comment and we can discuss and resolve it .

Comments

Popular posts from this blog

How to create Connected App in Salesforce and get access Token?

Update Custom Fonts in Salesforce Experience/Community Site

Error Logging Framework in Salesforce