Lightning Datatable With Pagination and Searching and Sorting

DataTable With Search/Pagination/Sorting LWC

LWC

I am sharing code of Data Table with search and pagination and sorting in columns in Lightning Web Component

dataTableWithPagination.html

<template>
    <lightning-card title="Lightning Datatable With Pagination and Searching">
        <div class="slds-m-around_medium">

            <lightning-input 
                type="search" 
                onchange={handleKeyChange} 
                class="slds-m-bottom_small"           
                label="Search" 
                value={searchKey}>
            </lightning-input>
            
            <lightning-datatable 
                data-id="table" 
                key-field="Id" 
                data={data} 
                columns={columns} 
                sorted-by={sortedBy}
                sorted-direction={sortedDirection} 
                onrowselection ={onRowSelection} 
                selected-rows={allSelectedRows} 
                onsort={sortColumns}>
           </lightning-datatable>
           </br>

            <lightning-layout horizontal-align="space">
                <lightning-layout-item flexibility="auto">
                    <lightning-button 
                        label="Previous" 
                        icon-name="utility:chevronleft" 
                        onclick={previousHandler}>
                    </lightning-button>
                </lightning-layout-item>
                <lightning-layout-item flexibility="auto">
                    Page {page} of {totalPage}
                </lightning-layout-item>
                <lightning-layout-item flexibility="auto">
                    <lightning-button 
                        label="Next" 
                        icon-name="utility:chevronright" 
                        icon-position="right"
                        onclick={nextHandler}>
                    </lightning-button>
                </lightning-layout-item>
            </lightning-layout>
        </div>
    </lightning-card>

</template>

dataTableWithPagination.js

import { LightningElement, wire, api, track} from 'lwc';
import { refreshApex } from '@salesforce/apex';
import getOpps from '@salesforce/apex/OpportunityController.getOpps';

const columns = [{
    label: 'Name',
    fieldName: 'Name',
    type: 'text',
    sortable: true
},
{
    label: 'Stage',
    fieldName: 'StageName',
    sortable: true
},
{
    label: 'Close Date',
    fieldName: 'CloseDate',
    sortable: true
}
];


export default class DataTableWithPagination extends LightningElement {
    @track value;
    @track error;
    @track data;
    @api sortedDirection = 'asc';
    @api sortedBy = 'Name';
    @api searchKey = '';
    result;
    @track allSelectedRows = [];
    @track page = 1; 
    @track items = []; 
    @track data = []; 
    @track columns; 
    @track startingRecord = 1;
    @track endingRecord = 0; 
    @track pageSize = 5; 
    @track totalRecountCount = 0;
    @track totalPage = 0;
    isPageChanged = false;
    initialLoad = true;
    mapoppNameVsOpp = new Map();

    @wire(getOpps, {searchKey: '$searchKey', sortBy: '$sortedBy', sortDirection: '$sortedDirection'})
    wiredAccounts({ error, data }) {
        if (data) {
            this.processRecords(data);
            this.error = undefined;
        } else if (error) {
            this.error = error;
            this.data = undefined;
        }
    }

    processRecords(data){

        console.log('data==>>> '+JSON.stringify(data));
        this.items = data;
        this.totalRecountCount = data.length; 
        this.totalPage = Math.ceil(this.totalRecountCount / this.pageSize); 
        
        this.data = this.items.slice(0,this.pageSize); 
        this.endingRecord = this.pageSize;
        this.columns = columns;
    }

    previousHandler() {
        this.isPageChanged = true;
        if (this.page > 1) {
            this.page = this.page - 1; //decrease page by 1
            this.displayRecordPerPage(this.page);
        }
          var selectedIds = [];
          for(var i=0; i<this.allSelectedRows.length;i++){
            selectedIds.push(this.allSelectedRows[i].Id);
          }
        this.template.querySelector(
            '[data-id="table"]'
          ).selectedRows = selectedIds;
    }

    nextHandler() {
        this.isPageChanged = true;
        if((this.page<this.totalPage) && this.page !== this.totalPage){
            this.page = this.page + 1; //increase page by 1
            this.displayRecordPerPage(this.page);            
        }
          var selectedIds = [];
          for(var i=0; i<this.allSelectedRows.length;i++){
            selectedIds.push(this.allSelectedRows[i].Id);
          }
        this.template.querySelector(
            '[data-id="table"]'
          ).selectedRows = selectedIds;
    }

    displayRecordPerPage(page){

        this.startingRecord = ((page -1) * this.pageSize) ;
        this.endingRecord = (this.pageSize * page);

        this.endingRecord = (this.endingRecord > this.totalRecountCount) 
                            ? this.totalRecountCount : this.endingRecord; 

        this.data = this.items.slice(this.startingRecord, this.endingRecord);
        this.startingRecord = this.startingRecord + 1;
    }    
    
    sortColumns( event ) {
        this.sortedBy = event.detail.fieldName;
        this.sortedDirection = event.detail.sortDirection;
        return refreshApex(this.result);
        
    }
    
    onRowSelection(event){
        if(!this.isPageChanged || this.initialLoad){
            if(this.initialLoad) this.initialLoad = false;
            this.processSelectedRows(event.detail.selectedRows);
        }else{
            this.isPageChanged = false;
            this.initialLoad =true;
        }
        
    }
    processSelectedRows(selectedOpps){
        var newMap = new Map();
        for(var i=0; i<selectedOpps.length;i++){
            if(!this.allSelectedRows.includes(selectedOpps[i])){
                this.allSelectedRows.push(selectedOpps[i]);
            }
            this.mapoppNameVsOpp.set(selectedOpps[i].Name, selectedOpps[i]);
            newMap.set(selectedOpps[i].Name, selectedOpps[i]);
        }
        for(let [key,value] of this.mapoppNameVsOpp.entries()){
            if(newMap.size<=0 || (!newMap.has(key) && this.initialLoad)){
                const index = this.allSelectedRows.indexOf(value);
                if (index > -1) {
                    this.allSelectedRows.splice(index, 1); 
                }
            }
        }
    }
    
    handleKeyChange( event ) {
        this.searchKey = event.target.value;
        var data = [];
        for(var i=0; i<this.items.length;i++){
            if(this.items[i]!= undefined && this.items[i].Name.includes(this.searchKey)){
                data.push(this.items[i]);
            }
        }
        this.processRecords(data);
    }


}

dataTableWithPagination.js-meta.xml

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

Leave a Reply