Client side pagination and search in lightning web component
In this example, you have create one apex class and one lwc. In the apex handler i am using account object records but you can use any objects as per your need.
AccountHandler.apxc
public class AccountHandler {ClientSidePagination.html
@AuraEnabled(cacheable=true)
public static List<Account> getAccounts(String searchKey, String sortBy, String sortDirection) {
String query = 'SELECT Id, Name,Phone,Type FROM Account';
if (String.isNotEmpty(searchKey)) {
String key = '%' + searchKey + '%';
query += ' WHERE Name LIKE :key';
}
if (String.isNotEmpty(sortBy) && String.isNotEmpty(sortDirection)){
query += ' ORDER BY ' + sortBy + ' ' + sortDirection;
}
return Database.query(query);
}
}
<template>ClientSidePagination.js
<template if:true={loader}>
<lightning-spinner alternative-text="Loading..." size="small"></lightning-spinner>
</template>
<lightning-layout>
<lightning-layout-item padding="around-small" size="4">
<lightning-combobox style="width:80px;" name="StageName" label="Show Entries" value={pageSize} options={options}
onchange={handleChange}></lightning-combobox>
</lightning-layout-item>
<lightning-layout-item style="padding-top: 34px;" size="4">
<center>
<lightning-button icon-name="utility:desktop" label="Show Selected Account" variant="brand" onclick={showSelectedAccounts}></lightning-button>
</center>
</lightning-layout-item>
<lightning-layout-item padding="around-small" size="4">
<lightning-input type="search" onchange={handleKeyChange} class="slds-m-bottom_small" label="Search"
value={searchKey} placeholder="Type Account Name..">
</lightning-input>
</lightning-layout-item>
</lightning-layout>
<lightning-card title="Client Side Pagination With Search" icon-name="standard:account">
<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>
<div class="slds-m-around_medium">
<center>
<lightning-button label="Previous" variant="brand" icon-name="utility:chevronleft" onclick={previousHandler}>
</lightning-button>
Page {page} of {totalPage}
<lightning-button label="Next" variant="brand" icon-name="utility:chevronright" icon-position="right"
onclick={nextHandler}>
</lightning-button>
</center>
</div>
</lightning-card>
<template if:true={isModalOpen}>
<!-- Modal/Popup Box LWC starts here -->
<section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
<div class="slds-modal__container">
<!-- Modal/Popup Box LWC header here -->
<header class="slds-modal__header">
<button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" title="Close" onclick={closeModal}>
<lightning-icon icon-name="utility:close" alternative-text="close" variant="inverse" size="small" ></lightning-icon>
<span class="slds-assistive-text">Close</span>
</button>
<h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">Selected Account List</h2>
</header>
<!-- Modal/Popup Box LWC body starts here -->
<div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
<p>
<lightning-datatable data-id="SelectedAcctable" key-field="Id" data={allSelectedRows} columns={columns}
hide-checkbox-column="false" show-row-number-column="true">
</lightning-datatable>
</p>
</div>
<!-- Modal/Popup Box LWC footer starts here -->
<footer class="slds-modal__footer">
<button class="slds-button slds-button_destructive" onclick={closeModal} title="Close">Close</button>
</footer>
</div>
</section>
<div class="slds-backdrop slds-backdrop_open"></div>
</template>
</template>
import { LightningElement, wire, api, track } from 'lwc';ClientSidePagination.js-meta.xml
import { refreshApex } from '@salesforce/apex';
import getAccounts from '@salesforce/apex/AccountHandler.getAccounts';
const columns = [
{ label: 'Name', fieldName: 'Name', type: 'text', sortable: true },
{ label: 'Phone', fieldName: 'Phone', sortable: true },
{ label: 'Type', fieldName: 'Type', sortable: true }
];
export default class ClientSidePagination extends LightningElement {
@track loader = false;
@track isModalOpen = false;
@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;
mapAccount = new Map();
get options() {
return [
{ label: '5', value: '5' },
{ label: '10', value: '10' },
{ label: '15', value: '15' },
];
}
handleChange(event) {
this.pageSize = event.detail.value;
this.processRecords(this.items);
}
@wire(getAccounts, { searchKey: '$searchKey', sortBy: '$sortedBy', sortDirection: '$sortedDirection' })
wiredAccounts({ error, data }) {
this.loader = true;
if (data) {
this.loader = false;
this.processRecords(data);
this.error = undefined;
} else if (error) {
this.loader = false;
this.error = error;
this.data = undefined;
}
}
processRecords(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;
}
//clicking on previous button this method will be called
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;
}
//clicking on next button this method will be called
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;
}
//Method to displays records page by page
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);
}
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);
}
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(selectedAccounts) {
var newMap = new Map();
for (var i = 0; i < selectedAccounts.length; i++) {
if (!this.allSelectedRows.includes(selectedAccounts[i])) {
this.allSelectedRows.push(selectedAccounts[i]);
}
this.mapAccount.set(selectedAccounts[i].Name, selectedAccounts[i]);
newMap.set(selectedAccounts[i].Name, selectedAccounts[i]);
}
for (let [key, value] of this.mapAccount.entries()) {
if (newMap.size <= 0 || (!newMap.has(key) && this.initialLoad)) {
const index = this.allSelectedRows.indexOf(value);
if (index > -1) {
this.allSelectedRows.splice(index, 1);
}
}
}
}
showSelectedAccounts() {
if (this.allSelectedRows != null && this.allSelectedRows.length > 0) {
this.isModalOpen = true;
}
else {
alert('Please select account record..!!');
}
}
closeModal() {
this.isModalOpen = false;
}
}
<?xml version="1.0"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>51.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>
Output:
No comments:
Post a Comment