Building Interactive Data Tables in Salesforce Lightning Web Components
In Salesforce Lightning Web Components (LWC), displaying data in a visually appealing and interactive manner is crucial for enhancing user experience. One common requirement is to present data in a tabular format, allowing users to easily navigate, view details, and perform actions on individual records. In this blog post, we'll explore how to build a dynamic data table in LWC, fetch data from Salesforce, and incorporate interactive features like row navigation and map viewing.
Fetching Data
The first step in building our data table is to fetch the necessary data from Salesforce. We achieve this using Apex, Salesforce's server-side language. In our example, we have a simple Apex method getAccounts() that queries a list of accounts with specific fields.
public with sharing class AccountController {
// Apex method to fetch accounts
@AuraEnabled(cacheable=true)
public static List<Account> getAccounts() {
// Query to fetch accounts with specific fields
return [SELECT Id, Name, Industry, AnnualRevenue, Phone, BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingCountry FROM Account LIMIT 10];
}
}
Constructing the Data Table and Modal
<template>
<!-- Account List Card -->
<div if:true={showsearchscreen}>
<lightning-card title="Account List">
<div class="slds-m-around_medium">
<!-- Lightning Data Table -->
<lightning-datatable
key-field="Id"
data={accounts}
columns={columns}
onrowaction={handleRowAction}
hide-checkbox-column="true">
</lightning-datatable>
</div>
</lightning-card>
</div>
<!-- Modal Section -->
<template if:true={isModalOpen}>
<!-- Backdrop to blur the background -->
<div class="slds-backdrop slds-backdrop_open"></div>
<!-- Modal Dialog -->
<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 slds-modal_large" >
<div class="slds-modal__container" style="width:50%;">
<!-- Modal Header -->
<header class="slds-modal__header">
<!-- Close Button -->
<button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" onclick={closeModal} title="Close">
<lightning-icon icon-name="utility:close" size="medium" variant="inverse"></lightning-icon>
<span class="slds-assistive-text">Close</span>
</button>
<!-- Modal Title -->
<h2 class="slds-text-heading_medium slds-hyphenate" style="color: black;">Account Address Details</h2>
</header>
<!-- Modal Content -->
<div class="slds-modal__content" id="modal-content-id-1">
<!-- Address details and map -->
<div class="slds-grid slds-wrap">
<!-- Address details (left side) -->
<div class="slds-col slds-size_1-of-3" style="padding: 1rem;">
<p>Address:</p>
<p>{selectedAccount.BillingStreet}</p>
<p>{selectedAccount.BillingCity}, {selectedAccount.BillingState}</p>
<p>{selectedAccount.BillingPostalCode}</p>
<p>{selectedAccount.BillingCountry}</p>
</div>
<!-- Map (right side) -->
<div class="slds-col slds-size_2-of-3" style="padding: 1rem;">
<lightning-map map-markers={mapMarkers}></lightning-map>
</div>
</div>
</div>
</div>
</section>
</template>
</template>
Enhancing Interactivity
To add interactivity to our data table, we implement features like row navigation and viewing address details on a map. By handling row actions, such as clicking the "View" button, we can open a modal that displays the selected account's address and a map marker for its location.
// Import necessary modules from LWC and Salesforce
import { LightningElement, wire } from 'lwc';
import getAccounts from '@salesforce/apex/AccountController.getAccounts';
// Define the row actions for the data table
const actions = [
{ label: 'View on Map', name: 'View' }
];
// Define the columns for the data table
const columns = [
{
label: "Name",
fieldName: "AssignedToNameUrl",
type: "url",
typeAttributes:{label:{fieldName:"AssignedToName"},target: "_blank"}
},
{ label: 'Industry', fieldName: 'Industry', type: 'text' },
{ label: 'Phone', fieldName: 'Phone', type: 'phone' },
{ label: 'Street', fieldName: 'BillingStreet', type: 'text' },
{ label: 'City', fieldName: 'BillingCity', type: 'text' },
{ label: 'State', fieldName: 'BillingState', type: 'text' },
{ label: 'Postal Code', fieldName: 'BillingPostalCode', type: 'text' },
{ label: 'Country', fieldName: 'BillingCountry', type: 'text' },
{
type: 'action',
typeAttributes: { rowActions: actions, menuAlignment: 'right' }
}
];
// Export the default class for the LWC component
export default class DataTableLwc extends LightningElement {
// Define properties
columns = columns; // Define the columns for the data table
accounts = []; // Initialize accounts array to store fetched accounts
isModalOpen = false; // Flag to control the visibility of the modal
showsearchscreen = false; // Flag to control the visibility of the search screen
// Wire the Apex method to fetch accounts
@wire(getAccounts)
wiredAccounts({ error, data }) {
if (data) {
// If data is available, set showsearchscreen to true
this.showsearchscreen = true;
// Map the fetched accounts and format the AnnualRevenue
this.accounts = this.TransformWireData(data);
} else if (error) {
// Log an error if encountered while fetching accounts
console.error('Error loading accounts', error);
}
}
// Function to transform the data fetched from Apex
TransformWireData(response) {
return response.map((data) => {
// Construct URL for the account name
const assignedToNameUrl = `/${data.Id}`;
const assignedToName = data.Name;
// Return transformed data with URL and name
return {
...data,
AssignedToNameUrl :assignedToNameUrl,
AssignedToName : assignedToName
};
});
}
// Handle row actions (e.g., View on Map)
handleRowAction(event) {
const actionName = event.detail.action.name;
if (actionName === 'View') {
// If View action is triggered, prepare map markers and open the modal
this.selectedAccount = event.detail.row;
this.mapMarkers = [{
location: {
Street: this.selectedAccount.BillingStreet,
City: this.selectedAccount.BillingCity,
State: this.selectedAccount.BillingState,
PostalCode: this.selectedAccount.BillingPostalCode,
Country: this.selectedAccount.BillingCountry
},
title: this.selectedAccount.Name,
description: this.selectedAccount.Industry
}];
this.isModalOpen = true;
}
}
// Close the modal
closeModal() {
this.isModalOpen = false;
}
}
Conclusion
Building interactive data tables in Salesforce Lightning Web Components allows us to present data effectively and provide a seamless user experience. By leveraging the power of Apex for data retrieval and combining it with LWC's component architecture, we can create rich and engaging interfaces for users to interact with their Salesforce data.