In the world of Salesforce development, Lightning Web Components (LWC) have gained popularity for building interactive and responsive user interfaces. LWC provides a modern and efficient way to develop components that can be seamlessly integrated into the Salesforce ecosystem. In this blog post, we'll dissect a specific LWC code snippet that displays account and contact data in a tabular format and explores the concept of modals or popup boxes for further interaction.
HTML - AccountsDataToDisplay.html
<template>
<lightning-cardclass="card">
<divclass="container">
<tableborder="solid">
<thead>
<th>{Id}</th>
<th>{Name}</th>
</thead>
<tbody>
<templatefor:each={accounts}for:item="acc">
<trkey={acc.account.Id}>
<td>{acc.account.Id}</td>
<td>
<div onclick={openModal}><aid={acc.account.Id}value={acc.account.Id}>{acc.account.Name}</a></div>
</td>
</tr>
</template>
</tbody>
<templateif:true={isModalOpen}>
<!-- Modal/Popup Box LWC starts here -->
<sectionrole="dialog"tabindex="-1"aria-labelledby="modal-heading-01"aria-modal="true"
aria-describedby="modal-content-id-1"class="slds-modal slds-fade-in-open">
<divclass="slds-modal__container">
<!-- Modal/Popup Box LWC header here -->
<headerclass="slds-modal__header">
<button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse"
title="Close"onclick={closeModal}>
<lightning-iconicon-name="utility:close"alternative-text="close"variant="inverse"
size="small"></lightning-icon>
<spanclass="slds-assistive-text">Close</span>
</button>
<h2 id="modal-heading-01"class="slds-text-heading_medium slds-hyphenate">{accountName}</h2>
</header>
<!-- Modal/Popup Box LWC body starts here -->
<div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
<template if:true={checkTrue}>
<ulstyle=" list-style-type: circle;padding-left:7%">
<tableclass="modalTable">
<tbodystyle="text-align:center">
<templatefor:each={contactListShown}for:item="con">
<trkey={con.key}>
<td> <b>{con.Value}</b></td>
<td class="viewBtn">
<lightning-buttonvalue={con.key} label="View Contact" onclick={navigateToViewContactPage}></lightning-button>
</td>
</tr>
</template>
</tbody>
</table>
</ul>
</template>
<template if:false={checkTrue}>
<p>{NoContacts}</p>
</template>
</div>
</div>
</section>
<divclass="slds-backdrop slds-backdrop_open"></div>
</template>
</table>
</div>
</lightning-card>
</template>
Displaying Account Data
The initial part of the code focuses on rendering the account data in a tabular format. It uses the lightning-card component to create a visually appealing container. Inside the card, a table structure is used to organize the data. The thead element represents the table header, defining two columns: "Id" and "Name."
The tbody element contains a template directive, which leverages iteration using the for:each attribute. This iterates over an array of accounts and assigns each item to the acc variable. For every account, a tr (table row) element is generated with a unique key attribute.
Inside each row, the account's Id and Name are displayed using td (table data) elements. The style attribute is used to center-align the Id value.
Modal/Popup Box
The next part of the code introduces the concept of a modal or popup box, which provides additional information upon user interaction. The modal is conditionally rendered based on the value of the isModalOpen property.
The modal is implemented using the section element with the role of "dialog." It is visually highlighted using the CSS classes slds-modal and slds-fade-in-open. The aria-* attributes ensure accessibility by providing descriptive information to assistive technologies.
Within the modal, a header section (slds-modal__header) displays the account name as the title. A close button with an associated icon (lightning-icon) is also provided for dismissing the modal. The content of the modal is enclosed within the slds-modal__content class.
Displaying Contact Data in Modal
The modal's content varies based on a condition evaluated by the checkTrue property. If the condition is met, a list of contacts is displayed in a tabular format. The contacts are iterated over using the for:each directive, similar to the account rendering. Each contact is represented by a tr element with a unique key.
The contact's value is displayed using the td element, and a button labeled "View Contact" is rendered using the lightning-button component. Clicking this button triggers the navigateToViewContactPage function.
In case the checkTrue condition is not met, a simple message stating "No Contacts" is displayed within the modal.
JS - AccountsDataToDisplay.js
import { LightningElement, wire,track } from'lwc';
import getAccounts from'@salesforce/apex/AccountController.getAccountList';
import Name from'@salesforce/label/c.Name';
import Id from'@salesforce/label/c.Id';
import NoContacts from'@salesforce/label/c.No_Contacts';
import {ShowToastEvent} from 'lightning/platformShowToastEvent';
import { NavigationMixin } from 'lightning/navigation';
export default classAccountContactsDisplay extendsNavigationMixin(LightningElement) {
accounts;
AccountMap= [];
@trackaccountName;
accountList= [];
@trackcheckTrue = false;
@trackcontactListShown;
@trackisModalOpen = false;
Id= Id;
Name= Name;
NoContacts= NoContacts;
@wire(getAccounts) getAccount({data,error}){
if(data){
this.accounts=data;
for(leti = 0; i <data.length ; i++){
letcontacts = data[i]["account"]["Contacts"];
letcontactList = [];
if(contacts){
for(letj = 0; j <contacts.length; j++){
letName = contacts[j]["FirstName"] != null? contacts[j]["FirstName"] + contacts[j]["LastName"]:contacts[j]["LastName"];
contactList.push({"key":contacts[j]["Id"],"Value":Name});
}
}
this.AccountMap.push({"key":data[i]["account"]["Id"]+","+data[i]["account"]["Name"],"value":JSON.stringify(contactList)});
}
}
elseif(error){
this.ShowToastEventError(error);
}
};
// Navigate to View Contact Page
navigateToViewContactPage(event) {
letkey = event.target.value;
console.log('key>>>'+key);
this[NavigationMixin.Navigate]({
type:'standard__recordPage',
attributes: {
"recordId":key,
"objectApiName":"Contact",
"actionName":"view",
},
});
}
handleClick(event){
letvalue = event.target.id;
letId = value.substring(0,18);
this.AccountMap.forEach(element=> {
letkey = JSON.stringify(element["key"]);
letmatchID = key.split(",")[0];
if(matchID.match(Id)){
letname = key.split(",")[1];
letlen = name.length;
this.accountName= name.substring(0,len-1);
letcontacts = element["value"];
console.log("contact"+contacts);
if(contacts.length> 2){
for(leti = 0; i <contacts.length ; i++){
this.contactListShown= JSON.parse(contacts);
}
this.checkTrue= true;
}
else{
this.checkTrue= false;
}
}
});
}
ShowToastEventError(error){
constevent = newShowToastEvent({
title:"Error",
message:error,
variant:"Error",
});
this.dispatchEvent(event);
}
openModal(event) {
// to open modal set isModalOpen tarck value as true
this.isModalOpen= true;
this.handleClick(event);
}
closeModal() {
// to close modal set isModalOpen tarck value as false
this.isModalOpen= false;
}
submitDetails() {
// to close modal set isModalOpen tarck value as false
//Add your code to call apex method or do some processing
this.isModalOpen= false;
}
}
Importing Dependencies and Class Definition
The component imports necessary modules, including the LightningElement, wire, track, ShowToastEvent, and NavigationMixin, from the LWC and Lightning platforms.
The component class AccountsDataToDisplay extends NavigationMixin(LightningElement), allowing the component to utilize the navigation mixin to navigate to the contact record page.
Class Properties
The component defines various properties using the @track decorator. These properties include accounts, AccountMap, accountName, accountList, checkTrue, contactListShown, and isModalOpen. These properties are used to store and track data within the component.
Wire Service - Retrieving Account Data
The @wire decorator is used to call the getAccounts Apex method, which retrieves a list of accounts. The wire service automatically handles the retrieval of data from the server and updates the accounts property when the data is available. If an error occurs, the showToastEventError method is called to display an error toast.
Apex Class-
AccountController.cls
public classAccountController{
@AuraEnabled(cacheable=True)//Get Account Records
public static List<AccountWrapper> getAccountList(){
return AccountProcessor.getdomain();
}
}
AccountWrapper.cls
public class AccountWrapper {
@AuraEnabled
public Account account;
public AccountWrapper(Account account) {
this.account = account;
}
}
AccountProcessor.cls
public class AccountProcessor {
public static List<AccountWrapper> getdomain() {
List<AccountWrapper> processedData = new List<AccountWrapper>();
for(Account acc : AccountDomain.getAccounts()) {
processedData.add(new AccountWrapper(acc));
}
return processedData;
}
}
AccountDomain.cls
public without sharing class AccountDomain {
@AuraEnabled(Cacheable= True)
public static List<Account> getAccounts() {
return [
Select
Id,
Name,
AccountNumber,
Phone,
Industry,
(
SELECT
Id,
FirstName,
LastName
From
Contacts
)
FROM
Account
LIMIT
200
];
}
}
Processing Account and Contact Data
Inside the wire method, the retrieved account data is processed to create a mapping between account IDs and contact details. For each account, the associated contacts are extracted and stored in a contactList. The AccountMap is then populated with the account ID and name as the key and the contactList as the value.
Handling User Interaction
The handleClick method is triggered when the user clicks on an account's name within the table. It retrieves the account's ID and uses it to find the associated contactList in the AccountMap. The accountName property is updated with the account's name, and the checkTrue property is set based on whether there are contacts available. If there are contacts, they are assigned to the contactListShown property.
The navigateToViewContactPage method is called when the user clicks the "View Contact" button in the modal. It extracts the contact's ID from the event and uses the navigation mixin to navigate to the contact's record page.
Modal Functionality
The openModal method is triggered when the user clicks on the account name, and it opens the modal by setting the isModalOpen property to true. It also calls the handleClick method to populate the modal with the relevant data.
The closeModal method is called when the user clicks the close button in the modal, and it closes the modal by setting the isModalOpen property to false.
The submitDetails method is currently a placeholder for any additional functionality or processing that you may want to include when submitting the modal details.
Displaying Toast Messages
The showToastEventError method is responsible for displaying an error toast when an error occurs during the retrieval of account data. It creates a new ShowToastEvent instance with the appropriate parameters and dispatches the event to display the toast.
CSS - AccountsDataToDisplay.css
body{
color: #000;
padding-left: 200px;
}
th {
text-align: center;
}
td{
text-align: center;
}
.container{
display: flex;
justify-content: center;
}
table{
width: 50%;
}
.modalTable{
width: 100%;
}
.viewBtn{
padding-bottom:10px;
}
XML- AccountsDataToDisplay.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>56.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
<target>lightning__Tab</target>
</targets>
</LightningComponentBundle>
.Throughout the code walkthrough, we covered various key aspects of the implementation. This included using the wire service to retrieve data from an Apex method, processing and mapping the data for efficient usage, handling user interactions, and incorporating modal functionality for displaying additional details and navigation.
Remember, this code serves as a foundation that you can build upon and customize to suit your specific needs. Salesforce's extensive documentation and developer resources are great references for exploring additional LWC capabilities and best practices.
We hope you found this blog post informative and inspiring. Feel free to experiment with the code, add your own features, and continue exploring the world of Lightning Web Components.
We hope this blog post provided you with valuable insights into building a Lightning Web Component for fetching and displaying account and contact data in Salesforce. By leveraging the power of LWC, you can create dynamic and interactive user interfaces to enhance the user experience.
If you'd like to see the code and resources used in this project, you can access the repository on GitHub.To access the AVENOIRBLOGS repository, click here. Feel free to explore the code and use it as a reference for your own projects.
Happy Coding! You can leave a comment to help me understand how the blog helped you. If you need further assistance, please contact us. You can click "Reach Us" on the website and share the issue with me.
Blog Credit:
N. Mehra
Salesforce Developer
Avenoir Technologies Pvt. Ltd.
Reach us: team@avenoir.ai