Develop Dynamic Salesforce Lightning Datatables

Salesforce Dynamic Lightning Datatable Configured in Lightning App Builder

Enhance your Salesforce Lightning Datatables with Dynamic Features

Have you ever wanted to develop dynamic Salesforce Lightning Datatables? Creating custom and dynamic datatables for Salesforce lightning-datatable allows for greater flexibility and tailored user experiences.

Moreover, in this guide, you’ll discover how to take your Salesforce Lightning Datatables to the next level by integrating dynamic features that adapt to your specific needs. Whether you’re working with complex data structures or aiming to improve user experiences, this guide provides step-by-step instructions.

Key Topics Covered:

  • Introduction to lightning-datatable: Understand the core capabilities of the lightning-datatable component and its potential for dynamic data presentation.
  • Introduction to LWC targetConfigs: Learn to configure a Lightning Web Component for Lightning App Builder.
  • Dynamic Data Integration: Explore methods for dynamically loading and managing data within your datatable, ensuring real-time updates and improved performance.
  • Practical Examples and Use Cases: Review real-world examples and best practices for applying dynamic features to various scenarios.

In summary, by the end of this guide you will master the skills to develop a Salesforce Lightning Datatable that exceeds user expectations and delivers a flexible solution for data management.

Dynamic Salesforce Lighting Datatable

Example Dynamic Lightning Data Tables in LWC

Overall this tutorial demonstrates the implementation of a Dynamic Lightning Data Table using Lightning Web Components (LWCs). It begins by creating a new LWC to present data in a table format via the lightning-datatable component. The HTML code below includes a lightning-datatable.

<template>
    <lightning-card title="Custom Lightning Datatable Example">
        
           <lightning-datatable
                key-field="Id"
                data={records}
                columns={columns}>
            </lightning-datatable>
           
    </lightning-card>
</template>

Initialize the Lightning Datatables Data and Column Attributes

In a lightning-datatable, the columns attribute defines which columns are displayed, while the data attribute showcases the actual data or Salesforce records. The attributes sorted-by and sorted-direction allow for sorting columns in either ascending or descending order which we will discuss in further detail later.

To retrieve the columns and data values from our JavaScript file, first create a method in your Apex class that returns a list of SObjects. We return a list of SObjects because we want the lightning datatable to be dynamic, so it should be able to support any standard or custom Salesforce object. In addition, it should be able to dynamically display the fields. In order to retrieve this Salesforce data dynamically, we create the following Apex methods below.

public class DynamicDatatableController {
    
    /**
    * @description: get Salesforce records based on target configs configured by Salesforce Admin
    * @param     objApiName        Object API name specified in LWC
    * @param     fieldPaths        Comma delimited string of field API names specified in LWC
    * @param     whereClause       Where clause specified in LWC
    * @return    sobjList          Dynamic Salesforce records and info about the records
    */
    
    @AuraEnabled(cacheable=true)
    public static List<sObject> getDynamicRecords(String objApiName,String fieldPaths,String whereClause){
         List<sObject> sobjList = new List<sObject>();
        
         try {
              List<String> fieldPathsToQuery = getFieldPathsToQuery(objApiName, fieldPaths);
    
              String queryStr = 'SELECT ' + String.join(fieldPathsToQuery, ',') + ' FROM ' + objApiName;
    
              if(!String.isEmpty(whereClause)){
                   queryStr = queryStr + ' WHERE ' + whereClause;
              }
                
              sobjList = Database.query(queryStr);

         } catch (exception e) {
              System.debug(e.getMessage());
        }
        
        return sobjList;
    }

    /**
    * @description: get Salesforce columns to display based on target configs configured by Salesforce Admin
    * @param     objApiName         bject API name specified in LWC
    * @param     fieldPaths         Comma delimited string of field API names specified in LWC
    * @return    dynamicColumnList  Dynamic String list of columns with properties to render in LWC
    */
    
    @AuraEnabled(cacheable=true)
    public static List<Map<String, String>> getDynamicColumns(String objApiName,String fieldPaths){
        List<String> fieldsList = getFieldPathsToQuery(objApiName, fieldPaths);
        Map<String, String> fieldTypeMap = getFieldTypes(objApiName, fieldsList);
        List<Map<String, String>> dynamicColumnList = new List<Map<String, String>>();

        // Loop through the keys
        for (String fieldName : fieldTypeMap.keySet()) {
            String fieldType = fieldTypeMap.get(fieldName);

            // Build the column map
            Map<String, String> columnMap = new Map<String, String>();
            columnMap.put('label', fieldName);
            columnMap.put('type', fieldType);
            columnMap.put('fieldName', fieldName);

            dynamicColumnList.add(columnMap);
        }
        return dynamicColumnList;
    }
    
    /**
    * @description: get dynamic field path to query for data table
    * @param   objApiName            Object API name specified in LWC
    * @param   fieldPaths            Comma delimited string of field API names specified in LWC
    * @return  fieldPathsToQuery     List of field paths to query with no spaces (ex:Id,Name,Email,Phone,Account.Name)
    */
    
    private static List<String> getFieldPathsToQuery(String objApiName, String fieldPaths) {
        List<String> fieldPathsToQuery = new List<String>();
        
        for (String fieldPath : fieldPaths.split(',')) {
            fieldPath = fieldPath.trim();
            fieldPathsToQuery.add(fieldPath);
        }
        return fieldPathsToQuery;
    }

    /**
    * @description: get Salesforce field types based on target configs configured by Salesforce Admin
    * @param     objApiName        Object API name specified in LWC
    * @param     fieldPaths        Comma delimited string of field API names specified in LWC
    * @return    fieldTypes        Map data structure of field API name and field type
    */

    private static Map<String, String> getFieldTypes(String objectName, List<String> fieldNames) {
        Map<String, String> fieldTypes = new Map<String, String>();
        
        // Get the schema for the specified object
        Schema.SObjectType objType = Schema.getGlobalDescribe().get(objectName);
        
        if (objType != null) {
            Schema.DescribeSObjectResult describeResult = objType.getDescribe();
            Map<String, Schema.SObjectField> fields = describeResult.fields.getMap();
            
            // Iterate over the list of field names and retrieve their types
            for (String fieldName : fieldNames) {
                Schema.SObjectField field = fields.get(fieldName);
                if (field != null) {
                    Schema.DescribeFieldResult fieldDescribe = field.getDescribe();
                    fieldTypes.put(fieldName, fieldDescribe.getType().name().toLowerCase());
                } else {
                    fieldTypes.put(fieldName, 'Field not found');
                }
            }
        } else {
            System.debug('Object not found');
        }
        
        return fieldTypes;
    }
}

Firstly, the getDynamicRecords() method returns Salesforce records based on the properties configured by Salesforce Admin in Lightning App Builder. Secondly, the getDynamicColumns() method returns the columns that get displayed as specified in the Lightning App Builder. Finally, the other two methods, getFieldPathsToQuery() and getFieldTypes(), are private methods. They support modularity, reuse, and separation of concerns, which are key best practices in object-oriented programming (OOP).

Develop the JavaScript Methods

To develop dynamic Salesforce Lightning Datatables, we have first exposed the apex method with @AuraEnabled(cacheable=true). This allows the Apex method to be used in the JavaScript class created for our LWC. Next, we will create a JavaScript method that uses the exposed Apex class above. Here is the code snippet below:

import { LightningElement, api, track } from 'lwc';
import getDynamicRecords from '@salesforce/apex/DynamicDatatableController.getDynamicRecords';
import getDynamicColumns from '@salesforce/apex/DynamicDatatableController.getDynamicColumns';

export default class DynamicDatatable extends LightningElement {
    @api sfObject;
    @api sfFields;
    @track records = [];
    @track columns = [];

    connectedCallback(){
        getDynamicColumns({objApiName : this.sfObject, fieldPaths : this.sfFields})
        .then(data =>{ 
            this.columns = (data);
        })
        .catch(error => {
            console.log(error);
        })

        getDynamicRecords({objApiName: this.sfObject, fieldPaths: this.sfFields, whereClause : ""})
        .then(data =>{
            this.records = data;
        })
        .catch(error => {
            console.log(error);
        })
    }
}

After exposing the Apex methods, we then import the methods into our JavaScript class. Once the methods have been imported, we can either @wire the method or called the Apex method imperatively. In this example, we are calling the Apex methods imperatively in the connectedCallback() function. We can directly assign the columns property because our Apex method returns a List<Map<String, String>> data structure, which is the required format for lightning-datatables.

Expose the Dynamic Salesforce Lightning Datatable

Finally, we will expose our Dynamic LWC to the Lightning App Page, Lightning Record Page, and Lightning Home Page. Once the file is exposed, we define our targetConfigs. See the code snippet below!

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>61.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordPage">
                <property name="sfObject" label="Object" type="String" description="Salesforce Object API Name. Note: " />
                <property name="sfFields" label="Fields" type="String" description="Comma Delimited String of Field API Names. Note: " />
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

Conclusion: Optimize Your Salesforce Lightning Datatables with Dynamic Features

Developing dynamic Salesforce Lightning Datatables empowers you to create highly flexible and interactive data displays that cater to your specific needs. By mastering the techniques for integrating dynamic data you can build datatables that improve data management.

As you apply these practices, remember that the goal is to provide users with intuitive and responsive interfaces that adapt to their requirements. Keep experimenting and refining your approach to create even more dynamic and effective datatables. Happy developing!


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *