Lightning Web Components: Pagination & Multiple Rows Actions

In such scenarios, where requirement states to enable or disable the number of records (Eg: Pricebook etc) from Salesforce UI.

Components:

  1. customDataTable (Parent Comp - base component)
  2. pageSizeSetupForm (Child Comp - to set page size)
  3. paginationSetupForm (Child Comp - to navigate first, last, next and prev pages)
  4. dataTableResults (Child Comp - to show results as data table)
  5. ContactManager (Apex classes with aura enabled methods)
** components are created as a part of proof of concept. it can be modified and optimized as per requirement.**

Snippets:




Code:

customDataTable.html:

<template>
<lightning-card title="Contact List">
<c-page-size-setup-form rows-to-skip={rowsToSkip} onpagesizeselect={pageSizeHandler}></c-page-size-setup-form>
<c-data-table-results page-size={pageSize} rows-to-skip={rowsToSkip} onselectedrows={selectedRowsHandler}></c-data-table-results>
<c-pagination-setup-form page-size={pageSize} rows-to-skip={rowsToSkip} onsetrowstoskip={rowsToSkipHandler}></c-pagination-setup-form>
</lightning-card>
</template>


customDataTable.js


import { LightningElement, track } from 'lwc';

export default class CustomDataTable extends LightningElement {

@track pageSize;
@track rowsToSkip;

@track firstPage;
@track lastPage;

pageSizeHandler(event){
const pageSize = event.detail.size;
this.pageSize = pageSize;
const rowsToSkip = event.detail.rowsToSkip;
this.rowsToSkip = rowsToSkip;
console.log('In3 customDataTable: this.pageSize>>'+this.pageSize);
console.log('In3 customDataTable: this.rowsToSkip>>'+this.rowsToSkip);
}

rowsToSkipHandler(event){
console.log('In rowsToSkipHandler : this.rowsToSkip>>'+this.rowsToSkip);
const rowsToSkip = event.detail;
this.rowsToSkip = rowsToSkip;
console.log('In rowsToSkipHandler : this.rowsToSkip>>'+this.rowsToSkip);
const dataTableResultsComp = this.template.querySelector('c-data-table-results');
if(dataTableResultsComp){
dataTableResultsComp.rowsToSkip = this.rowsToSkip;
dataTableResultsComp.getContacts();
}
}
selectedRowsHandler(){
const dataTableResultsComp = this.template.querySelector('c-data-table-results');
if(dataTableResultsComp){
console.log('In selectedRowsHandler :this.rowsToSkip>> '+this.rowsToSkip);
dataTableResultsComp.rowsToSkip = this.rowsToSkip;
dataTableResultsComp.getContacts();
}
}

get recordFound(){
if(!this.rowsToSkip){
console.log('In recordFound: true: this.rowsToSkip >>'+this.rowsToSkip);
return true;
}
console.log('In recordFound: false: this.rowsToSkip >>'+this.rowsToSkip);
return false;
}
}


pageSizeSetupForm.html:

<template>
<lightning-layout multiple-rows>
<lightning-layout-item padding="around-small">
<lightning-combobox name="pageSize" placeholder="Size" label="Size" variant="label-hidden" value={selectedValue} options={pageSize} onchange={pageSizeChangeHandler}>
</lightning-combobox>
</lightning-layout-item>
</lightning-layout>
</template>


pageSizeSetupForm.js:

import { LightningElement, track, api } from 'lwc';

export default class PageSizeSetupForm extends LightningElement {
@track pageSize =[{label:'100',value:'100'},{label:'500',value:'500'}];
@api rowsToSkip;
pageSizeChangeHandler(event){
const pageSize = event.target.value;
console.log('pageSizeSetupForm: pageSize >> '+pageSize);
console.log('pageSizeSetupForm: this.rowsToSkip >> '+this.rowsToSkip);
if(this.rowsToSkip){
console.log('In1 pageSizeSetupForm: pageSize >> '+pageSize);
console.log('In1 pageSizeSetupForm: this.rowsToSkip >> '+this.rowsToSkip);
var pageSizeSetup = { size : pageSize, rowsToSkip : this.rowsToSkip };
const pageSizeChangeEvent = new CustomEvent('pagesizeselect',{detail : pageSizeSetup , bubbles : true});
this.dispatchEvent(pageSizeChangeEvent);
} else{
console.log('In2 pageSizeSetupForm: pageSize >> '+pageSize);
console.log('In2 pageSizeSetupForm: this.rowsToSkip >> '+this.rowsToSkip);
var pageSizeSetup = { size : pageSize, rowsToSkip : 0 };
const pageSizeChangeEvent = new CustomEvent('pagesizeselect',{detail : pageSizeSetup , bubbles : true});
this.dispatchEvent(pageSizeChangeEvent);
}
}
}


dataTableResults.html:


<template>
<lightning-layout multiple-rows>
<lightning-layout-item padding="around-small">
<lightning-button label="Bingo!" variant="neutral" onclick={getSelectedHandler}></lightning-button>
</lightning-layout-item>
<lightning-layout-item padding="horizontal-small">
<lightning-datatable
key-field="Id"
data={results}
columns={columns}>
</lightning-datatable>
</lightning-layout-item>
</lightning-layout>
</template>


dataTableResults.js:


import { LightningElement, track, wire, api } from 'lwc';
import getAllContacts from '@salesforce/apex/ContactManager.getAllContacts';
import getSelectedRecords from '@salesforce/apex/ContactManager.getSelectedRecords';
import {ShowToastEvent} from 'lightning/platformShowToastEvent';

const columns = [
{ label: 'Name', fieldName: 'Name', type:'text' },
{ label: 'Phone', fieldName: 'Phone', type: 'phone' },
{ label: 'Account', fieldName: 'Account.Name',type:'text' },
{ label: 'Status', fieldName: 'Status__c',type:'boolean'}
];

export default class DataTableResults extends LightningElement {

/*@wire(getAllContacts, {numberOfRowsToReturn : '$pageSize' ,numberOfRowsToSkip: '$rowsToSkip'})
result({data,error}){
if(data){
this.results = data;
}else if(error){
this.showToast('ERROR', error.body.message, 'error');
}
};*/

privatePageSize;
privateRowsToSkip;
firstTimeRun = false;
selected;
//@api rowsToSkip;
@track results;
@track columns = columns;

@api
get rowsToSkip(){
return this.privateRowsToSkip;
}

set rowsToSkip(value){
console.log('In setting :value >>'+value);
if(value){
this.privateRowsToSkip = value;
} else{
this.privateRowsToSkip = '0';
}

console.log('In setting :this.privateRowsToSkip >>'+this.privateRowsToSkip);

}

@api
get pageSize(){
return this.privatePageSize;
}

set pageSize(value){
console.log('In setting: this.privatePageSize >>'+this.privatePageSize);
console.log('In setting: value >>'+value);
if(value){
this.privatePageSize = value;
} else{
this.privatePageSize = '10';
}
console.log('In setting: this.privatePageSize >>'+this.privatePageSize);
console.log('In setting: this.privatePageSize: checking this.firstTimeRun >>'+this.firstTimeRun);
if(this.firstTimeRun){
console.log('In this.getContacts() call>>');
this.getContacts();
console.log('Out this.getContacts() call>>');
}

}

connectedCallback(){
console.log('In connected call>>');
this.firstTimeRun =true;
console.log('In connected call: this.firstTimeRun >>'+this.firstTimeRun);
this.getContacts();
console.log('Out connected call>>');
}

@api
getContacts(){
console.log('In getContacts() : this.privatePageSize >>'+this.privatePageSize);
console.log('In getContacts() : this.privateRowsToSkip >>'+this.privateRowsToSkip);
getAllContacts({numberOfRowsToReturn : parseInt(this.privatePageSize) ,numberOfRowsToSkip: parseInt(this.privateRowsToSkip)}).then((con) =>{
this.results = con;
console.log('datatable>>'+this.results);
}).catch((error) =>{
this.showToast('ERROR', error.body.message, 'error');
})
}

getSelectedHandler(){
var el = this.template.querySelector('lightning-datatable');
this.selected = el.getSelectedRows();
console.log('this.selected>>'+this.selected);
this.disableStatus(this.selected);
}

disableStatus(selected){
for(var i=0;i<selected.length; i++){
console.log('get All selected >>'+selected[i].Id);
}
getSelectedRecords({conList: selected});
const getSelectedEvent = new CustomEvent('selectedrows');
this.dispatchEvent(getSelectedEvent);
}

showToast(title, message, variant){
const evt= new ShowToastEvent({
title: title,
message: message,
variant: variant,
});
this.dispatchEvent(evt);
}
}


ContactManager.cls

public with sharing class ContactManager {

@AuraEnabled
public static List<Contact> getAllContacts(Integer numberOfRowsToReturn, Integer numberOfRowsToSkip){

Database.QueryLocator qResult= Database.getQueryLocator([Select Id, Name, Phone, Account.Name,Status__c FROM Contact WHERE Status__c=true ORDER BY Account.CreatedDate ASC LIMIT 10000]);
Database.QueryLocatorIterator queryIterator = qResult.iterator();
List<Contact> conList= new List<Contact>();
while(queryIterator.hasNext()){
conList.add((contact) queryIterator.next());
}
List<Contact> resultList= new List<Contact>();
if(!conList.isEmpty()){
System.debug('Size conlist>> '+conList.size());
if(numberOfRowsToSkip+numberOfRowsToReturn < conList.size()){
for(Integer i=numberOfRowsToSkip;i<(numberOfRowsToSkip+numberOfRowsToReturn);i++){
resultList.add(conList.get(i));
}
} else{
Integer listSize= conList.size();
for(Integer i=numberOfRowsToSkip;i<listSize;i++){
resultList.add(conList.get(i));
}
}

System.debug('Size resultList >> '+resultList.size());
return resultList;
}
return null;
}

@AuraEnabled(cacheable=true)
public static Integer getContactsCount(){
return [SELECT count() FROM Contact WHERE Status__c=true LIMIT 10000];
}

@AuraEnabled
public static void getSelectedRecords(List<Contact> conList){
List<Contact> resultList = new List<Contact>();
for(Contact con: conList){
if(con.status__c)
con.status__c = false;
else
con.status__c = true;
resultList.add(con);
}
System.debug('resultList>>'+resultList);
update resultList;
}

}

No comments:

Post a Comment