Here is the code to display data in LWC Datatable with pagination and keep selected rows persistent between each page.
accountsTable.html :
<template>
<lightning-card
variant="Narrow"
title="Partner Lookup"
icon-name="standard:contact"
class="slds-var-m-around_small"
>
<lightning-button
variant="brand"
icon-name="utility:email"
label="Send Email"
title="Brand action"
slot="actions"
onclick={openEmailPopup}
disabled={disableEmail}
>
</lightning-button>
<div class="slds-card__body slds-card__body_inner">
<template if:true={showLoading}>
<lightning-spinner
alternative-text="Loading"
size="medium"
class="spinnerClass"
variant="brand"
>
</lightning-spinner>
</template>
<lightning-input
type="search"
class="slds-size_4-of-12 slds-var-p-bottom_small"
label="Company"
value={searchKey}
onchange={handleSearchChange}
>
</lightning-input>
<template if:false={noData}>
<lightning-datatable
data-id="table"
key-field="Id"
data={data}
columns={columns}
onrowselection={onRowSelection}
selected-rows={allSelectedRows}
class="slds-table_bordered"
>
</lightning-datatable>
<div slot="footer">
<lightning-layout class="slds-var-p-around_small">
<lightning-layout-item class="slds-size_2-of-12">
<lightning-button
label="Previous"
icon-name="utility:chevronleft"
onclick={previousHandler}
disabled={disbalePrevious}
>
</lightning-button>
</lightning-layout-item>
<lightning-layout-item class="slds-size_2-of-12">
Page {page} of {totalPage}
</lightning-layout-item>
<lightning-layout-item class="slds-size_2-of-12">
<lightning-button
label="Next"
icon-name="utility:chevronright"
icon-position="right"
onclick={nextHandler}
disabled={disbaleNext}
>
</lightning-button>
</lightning-layout-item>
</lightning-layout>
</div>
</template>
<template if:true={noData}>
<p class="slds-text-heading_small slds-var-p-top_small">
No matching Accounts to display.
</p>
</template>
</div>
</lightning-card>
<template if:true={showModal}>
<section aria-modal="true" class="slds-modal slds-fade-in-open">
<div class="slds-modal__container">
<header class="slds-modal__header">
<h2 class="slds-text-heading_small">Send Email</h2>
<lightning-button-icon
class="slds-modal__close"
icon-name="utility:close"
variant="bare-inverse"
onclick={closeModal}
alternative-text="Close"
title="Close"
>
</lightning-button-icon>
</header>
<div
class="slds-var-p-around_small slds-modal__content modalBody slds-is-relative"
>
<template if:true={showModelLoading}>
<lightning-spinner
alternative-text="Loading"
size="medium"
class="spinnerClass"
variant="brand"
>
</lightning-spinner>
</template>
<lightning-layout multiple-rows="true" horizontal-align="space">
<lightning-layout-item size="12">
<lightning-input
name="recipients"
required="true"
value={recipients}
label="Recipients"
onchange={onChangeRecipient}
>
</lightning-input>
</lightning-layout-item>
<lightning-layout-item size="12">
<lightning-combobox
name="template"
label="Template"
value={selectedTemplate}
placeholder="Select Template"
options={templateOptions}
onchange={handleTemplateChange}
>
</lightning-combobox>
</lightning-layout-item>
<lightning-layout-item size="12">
<lightning-input
name="subject"
required="true"
value={subject}
label="Subject"
onchange={onChangeSubject}
>
</lightning-input>
</lightning-layout-item>
<lightning-layout-item size="12">
<lightning-input-rich-text
value={htmlBody}
label="Content"
label-visible="true"
share-with-entity-id={recordId}
required="true"
onchange={onChangeContent}
>
</lightning-input-rich-text>
</lightning-layout-item>
</lightning-layout>
</div>
<footer class="slds-modal__footer">
<lightning-button
variant="neutral"
label="Cancel"
title="Cancel"
onclick={closeModal}
class="slds-var-p-right_small"
>
</lightning-button>
<lightning-button
variant="brand"
icon-name="utility:send"
label="Send"
title="Send"
onclick={onClickSendEmail}
>
</lightning-button>
</footer>
</div>
</section>
<div class="slds-backdrop slds-backdrop_open"></div>
</template>
</template>
AccountsTable.js:
import { LightningElement, wire, api, track } from "lwc";
import getPartners from "@salesforce/apex/AccountController.getPartners";
import getRecipients from "@salesforce/apex/AccountController.getRecipients";
import getEmailBody from "@salesforce/apex/AccountController.getEmailBody";
import sendEmail from "@salesforce/apex/AccountController.sendEmail";
import emailTemplateLabel from "@salesforce/label/c.AccountTemplates";
import { ShowToastEvent } from "lightning/platformShowToastEvent";
const columns = [
{ label: "First Name", fieldName: "FirstName", type: "text" },
{ label: "Last Name", fieldName: "LastName", type: "text" },
{ label: "Email", fieldName: "Email", type: "text" },
{ label: "Phone", fieldName: "Phone", type: "Text" },
{ label: "Country", fieldName: "MailingCountry", type: "Text" }
];
const DELAY = 300;
export default class AccountsTable extends LightningElement {
@api recordId = null;
@track showLoading = true;
@track showModelLoading = true;
@track searchKey = "";
@track page = 1;
@track items = [];
@track data = [];
@track columns;
@track startingRecord = 1;
@track endingRecord = 0;
@track pageSize = 10;
@track totalRecountCount = 0;
@track totalPage = 0;
@track disableEmail = true;
@track allSelectedRows = [];
@track error;
@track showModal = false;
@track recipients;
@track selectedrecipients;
@track selectedTemplate;
@track subject;
@track htmlBody;
isPageChanged = false;
initialLoad = true;
@wire(getPartners, {
recId: "$recordId",
searchKey: "$searchKey"
})
wiredPartners({ error, data }) {
if (data) {
this.processRecords(data);
this.error = undefined;
this.showLoading = false;
} else if (error) {
this.error = error;
this.data = undefined;
this.showLoading = false;
}
}
processRecords(data) {
this.items = data;
this.totalRecountCount = data.length;
this.totalPage = Math.ceil(this.totalRecountCount / this.pageSize);
const arr = this.items.slice(0, this.pageSize);
const newArr = arr.map((object) => {
return { ...object, Id: object.Id + "-1" };
});
this.data = newArr;
this.endingRecord = this.pageSize;
this.columns = columns;
}
get disbalePrevious() {
return this.page == 1;
}
get disbaleNext() {
return this.page == this.totalPage;
}
previousHandler() {
this.showLoading = true;
this.isPageChanged = true;
if (this.page > 1) {
this.page = this.page - 1;
this.displayRecordPerPage(this.page);
}
this.showLoading = false;
}
nextHandler() {
this.showLoading = true;
this.isPageChanged = true;
if (this.page < this.totalPage && this.page !== this.totalPage) {
this.page = this.page + 1;
this.displayRecordPerPage(this.page);
}
this.showLoading = false;
}
displayRecordPerPage(page) {
this.startingRecord = (page - 1) * this.pageSize;
this.endingRecord = this.pageSize * page;
this.endingRecord =
this.endingRecord > this.totalRecountCount
? this.totalRecountCount
: this.endingRecord;
const arr = this.items.slice(this.startingRecord, this.endingRecord);
const newArr = arr.map((object) => {
return { ...object, Id: object.Id + "-" + page };
});
this.data = newArr;
this.startingRecord = this.startingRecord + 1;
this.template.querySelector(
'[data-id="table"]'
).selectedRows = this.allSelectedRows;
}
onRowSelection(event) {
if (!this.isPageChanged || this.initialLoad) {
this.initialLoad = false;
var selectedRows = event.target.selectedRows;
var allSelectedRows = this.allSelectedRows;
var currentPageNumber = this.page;
//Process the rows now
//Condition 1 -> If any new row selected, add to our allSelectedRows attribute
//Condition 2 -> If any row is deselected, remove from allSelectedRows attribute
//Solution - Remove all rows from current page from allSelectedRows attribute and then add again
//Removing all rows coming from curent page from allSelectedRows
var i = allSelectedRows.length;
if (i > 0) {
while (i--) {
var pageNumber = allSelectedRows[i].split("-")[1];
if (pageNumber && pageNumber == currentPageNumber) {
allSelectedRows.splice(i, 1);
}
}
}
selectedRows.forEach(function (row) {
allSelectedRows.push(row);
});
if (allSelectedRows.length > 0) {
this.disableEmail = false;
} else {
this.disableEmail = true;
}
this.allSelectedRows = allSelectedRows;
} else {
this.isPageChanged = false;
}
}
handleSearchChange(event) {
this.showLoading = true;
window.clearTimeout(this.delayTimeout);
const searchKey = event.target.value;
this.delayTimeout = setTimeout(() => {
this.searchKey = searchKey;
var data = [];
for (var i = 0; i < this.items.length; i++) {
if (
this.items[i] != undefined &&
this.items[i].FirstName.includes(this.searchKey)
) {
data.push(this.items[i]);
}
}
this.processRecords(data);
this.page = 1;
this.showLoading = false;
}, DELAY);
}
openEmailPopup() {
this.showModal = true;
this.showModelLoading = true;
var recs = [];
for (var i = 0; i < this.allSelectedRows.length; i++) {
recs.push(this.allSelectedRows[i].split("-")[0]);
}
getRecipients({ recIds: recs })
.then((result) => {
this.showModelLoading = false;
this.recipients = result;
this.selectedrecipients = result;
this.error = undefined;
})
.catch((error) => {
this.showModelLoading = false;
this.recipients = undefined;
this.selectedrecipients = undefined;
this.error = error;
});
}
get templateOptions() {
var options = emailTemplateLabel.split(";");
var resultMap = [];
for (let i = 0; i < options.length; i++) {
resultMap.push({
class: "optionClass",
label: options[i],
value: options[i]
});
}
return resultMap;
}
onChangeRecipient(event) {
this.recipients = event.detail.value;
}
onChangeSubject(event) {
this.subject = event.detail.value;
}
onChangeContent(event) {
this.htmlBody = event.detail.value;
}
handleTemplateChange(event) {
this.showModelLoading = true;
this.selectedTemplate = event.detail.value;
getEmailBody({ leadId: this.recordId, templateName: this.selectedTemplate })
.then((result) => {
this.showModelLoading = false;
for (var key in result) {
this.subject = key;
this.htmlBody = result[key];
}
this.error = undefined;
})
.catch((error) => {
this.showModelLoading = false;
this.error = error;
this.subject = undefined;
this.htmlBody = undefined;
});
}
get noData() {
return this.items.length == 0 ? true : false;
}
closeModal() {
this.closeEmailModel();
}
onClickSendEmail() {
if (
this.recipients == undefined ||
this.recipients == null ||
this.recipients == ""
) {
this.showToast("error", "Error", "Enter the Recipients");
} else if (
this.subject == undefined ||
this.subject == null ||
this.subject == ""
) {
this.showToast("error", "Error", "Enter the Subject");
} else if (
this.htmlBody == undefined ||
this.htmlBody == null ||
this.htmlBody == ""
) {
this.showToast("error", "Error", "Enter the Content");
} else {
this.showModelLoading = true;
sendEmail({
leadId: this.recordId,
toAddress: this.recipients,
subject: this.subject,
body: this.htmlBody
})
.then((result) => {
this.showToast("success", "Success!", "Email sent successfully.");
this.error = undefined;
this.closeEmailModel();
})
.catch((error) => {
this.showModelLoading = false;
this.error = error;
this.showToast("error", "Email sending failed!", this.error);
});
}
}
closeEmailModel() {
this.recipients = this.selectedrecipients;
this.selectedTemplate = undefined;
this.subject = undefined;
this.htmlBody = undefined;
this.showModelLoading = false;
this.showModal = false;
}
showToast(type, title, msg) {
const evt = new ShowToastEvent({
title: title,
message: msg,
variant: type,
mode: "dismissable"
});
this.dispatchEvent(evt);
}
}
public class AccountController {
@AuraEnabled(cacheable=true)
public static List<partnerData> getPartners(String recId, String searchKey){
String partnerName;
if(String.isNotBlank(searchKey)){
partnerName = searchKey+'%';
}
List<partnerData> partnerList = new List<partnerData>();
for(Contact con : [SELECT Id,FirstName,LastName,Email,Phone,MailingCountry From Contact where FirstName like:partnerName]){
partnerList.add(new partnerData(con));
}
return partnerList;
}
@AuraEnabled
public static String getRecipients(List<String> recIds){
Set<String> recSet = new Set<String>();
for(Contact con :
[SELECT Id,FirstName,LastName,Email,Phone,MailingCountry From Contact
Where Id IN:recIds order by Name]){
recSet.add(con.Email);
}
return String.join(new List<String>(recSet),';');
}
@AuraEnabled
public static map<string,string> getEmailBody(String leadId, String templateName){
map<string,string> emailmap = new map<string,string>();
EmailTemplate et = [select id,Name,Subject,Body from EmailTemplate where Name=:templateName];
Messaging.SingleEmailMessage email =
Messaging.renderStoredEmailTemplate(et.id, leadId ,null);
if(email.getHtmlBody() != null ){
emailmap.put(email.getSubject(),email.getHtmlBody());
}else{
emailmap.put(email.getSubject(),email.getPlainTextBody());
}
return emailmap;
}
@AuraEnabled
public static String sendEmail(String leadId,String toAddress,String subject,String body){
List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(toAddress.split(';'));
mail.setTargetObjectId(leadId);
// mail.setReplyTo('noreply@gmail.com'); // change it with your mail address.
// mail.setSenderDisplayName('salesforce User');
mail.setSubject(subject);
mail.setHtmlBody(body);
mail.setTreatTargetObjectAsRecipient(false);
mail.setSaveAsActivity(true);
mails.add(mail);
try{
Messaging.sendEmail(mails);
return 'Success';
}catch(exception e){
return e.getMessage();
}
}
public class partnerData{
@AuraEnabled
public string Id{get;set;}
@AuraEnabled
public string FirstName{get;set;}
@AuraEnabled
public string LastName{get;set;}
@AuraEnabled
public string Email{get;set;}
@AuraEnabled
public string Phone{get;set;}
@AuraEnabled
public string MailingCountry{get;set;}
public partnerData(Contactpartner){
this.Id = partner.Id;
this.FirstName = partner.FirstName;
this.LastName = partner.LastName;
this.Email = partner.Email;
this.Phone = partner.Phone;
this.MailingCountry = partner.MailingCountry ;
}
}
}
No comments:
Post a Comment