Close Menu
SalesforceCodex
    Facebook X (Twitter) Instagram
    Trending
    • Top 10 Salesforce Flow Features of Salesforce Summer ’25
    • Unlock the Power of Vibe Coding in Salesforce
    • How to Implement Dynamic Queueable Chaining in Salesforce Apex
    • How to Implement Basic Queueable Chaining in Salesforce Apex
    • How to Suppress PMD Warnings in Salesforce Apex
    • Top 10 PMD Issues Salesforce Developers Should Focus on in Apex
    • How to Use Graph API for Outlook-Salesforce Connection
    • Enhancing Performance with File Compression in Apex
    Facebook X (Twitter) Instagram
    SalesforceCodex
    Subscribe
    Tuesday, May 20
    • Home
    • Architecture
    • Salesforce
      • News
      • Apex
      • Integration
      • Books Testimonial
    • Questions
    • Certification
      • How to Prepare for Salesforce Integration Architect Exam
      • Certification Coupons
    • Integration Posts
    • Downloads
    • About Us
      • Privacy Policy
    SalesforceCodex
    Home»Salesforce»Generic DataTable in Lightning Web Component

    Generic DataTable in Lightning Web Component

    Dhanik Lal SahniBy Dhanik Lal SahniSeptember 3, 2020Updated:June 11, 20237 Comments8 Mins Read
    Facebook Twitter Pinterest LinkedIn Tumblr Email
    Generic DataTable in Lightning Web Component
    Share
    Facebook Twitter LinkedIn Pinterest Email

    A lightning-datatable component displays tabular data based on data rows and columns provided. We required this component on many pages in the project.
    Instead of putting this component on every page. We can create a reusable and configurable data table component.

    This blog will create a generic data table component that has a below configurable setting. It will populate data based on below requirement

    1. Based on the object and fields provided.
    2. Based on the apex method and fields provided.
    3. Based on provided records and fields

    It will have a configuration setting for enabling features like

    1. Pagination
    2. Editing
    3. Deleting
    4. Single Row Selection
    5. Sorting on Fields
    6. Field data searching

    Let us create a generic component based on the above requirement. We will go to each requirement step by step. First, let us handle the requirement to get data from Salesforce Org to show based on assigned properties.

    1. Based on the object and fields provided.

    As we will get the object name and field name as a parameter from the container/parent component. Let us get data from that object by dynamically creating SOQL.

    Let us create base class to create dynamic SOQL. Records should be fetched based on user’s access.

    Let us create a generic data selector class which will get data based on the provided object name and columns. SOQL will be created at runtime based on passed fields and object names. It has a cached and non-cached method to retrieve data. Call method based on your use case.

    Let us call this apex method in Lightning Web Component to get object records. We have to pass all setting variables to get the required data.

    
    fetchRecords() {
          return new Promise((resolve, reject) => {
          this.handleSpinner(true);
          let fields = this.getFields();
          if (fields) {
              this.sortBy = fields[0];
              fields = fields.join(',');
          }
          var field=fields;
          if(fields.slice(-1)===',')
          {
            field=fields.slice(0, -1);
          }
          const params = {
              objectName: this.objectName,
              fields: field,
              sortBy: this.sortBy,
              sortAsc: this.sortAsc,
              whereCondition: this.whereCondition,
              limitRecords: this.limit
          };
          if (this.cacheable) {
              getCachedRecords({params:params})
                    .then(map => resolve(this.getResolve(map.records)))
                    .catch(error => reject(this.getReject(error)));
          } else {
              getRecords({params:params})
              .then(map => resolve(this.getResolve(map.records)))
              .catch(error => {console.error(error)});
          } 
            });
      }
    

    2. Based on the apex method and fields

    The above approach will work when we need to get data from one object but what if we need to show data from multiple objects. In that case, we need an apex method to retrieve data. We have to call those apex methods imperatively. For this, we have to import all methods in the lightning web component.

    For the generic concept, we have to call a specific apex method based on the passed apex method parameter. For this specific apex method, we have to import that method in our LWC component but that will be difficult. To handle that in a generic way, we can use ICallable interface or we can use Repository class. In both approach, apex method will be called based on parameter.

    We will go with Repository class pattern for this use case.

    I have used AccountSelector class only for this post but if you need to call any other class code then you have to call that in repository class.

    Call this repository class from Lightning Web Component.

    Import repository class to call apex method

    import apexExecute from '@salesforce/apex/DataRepository.execute';

    Call this apex method using below code.

      fetchRecordFromApex=()=>
      {
        if (this.apexName !== '') {
            apexExecute({action:this.apexName,params:this.param})
            .then(result => {
                this.recordsInPage = result;
            })
            .catch(error => {
                this.error = error;
                console.log(JSON.stringify(error));
            });
    
        }
      }

    3. Based on provided records and fields

    In some scenario, we already have data in our component or we are passing data from flow then we just need to show that in datatable. In that use case, this option will work. We just have to pass records and column detail to components.

    Configurable Features:

    Now we are ready with data retrieval, let us create different configuration to generate data table with proper feature like pagination support, single row selection. Let is go each feature creation one by one.

    1. Pagination

    Datatable can return 100’s of records so we should support pagination. Right now this component supporting client-side pagination only. For pagination we need total record count and page record size. We can configure the page record size also in this component. Navigation buttons will be added to navigate back and next on the page.

    //Pagination Supported
    @api showPagination = false;
    //Pagination Size
    @api paginationSize=10;
    
    // page Size property
      @api
      get pageSize() {
          if (!isNotBlank(this._pageSize)) this._pageSize = 10;
          return parseInt(this._pageSize, 10);
      }
      set pageSize(value) {
          this._pageSize = value;
      }
    
    //Show Page Information 
      get pageNumberInfo() {
            if (this._records && this._records.length > 0) {
              this._paginationInfo.currentPage = (((this._startFromIndex + 1) / this.pageSize) - (((this._startFromIndex + 1) % this.pageSize) / this.pageSize) + ((((this._startFromIndex + 1) % this.pageSize) === 0) ? 0 : 1));
              return 'Page ' + this._paginationInfo.currentPage + ' of ' + this._paginationInfo.totalPages;
          }
          return 'Page 0 of 0';
      }

    2. Editing

    Editing is supported when we are retrieving data using objects. Lightning data service will be used to save edited records. Edit form will be opened in the dialog box. Dialog box code is added below.

    //Suport edit 
    @api editable = false;
    
    handleRowAction=event=>
        {
            const action = event.detail.action;
            const row = event.detail.row;
            if(row && this.objectName)
            { 
                this.recordId=row.Id;
                //in case edit button clicked. Open selected record in dialog box to edit
                if(action.name==='edit')
                {
                    if(this.template.querySelector('c-common-dialog'))
                    {
                        this.template.querySelector('c-common-dialog').openmodal();
                    }
                }
                //in case delete button clicked. delete selected record            if(action.name==='delete')
                {                    
                    this.deleteRecordById();
                }
            }
        }

    3. Deleting

    Deletion is supported in case data is shown using the object method. Using rowselection event we will know the currently selected row and then that record will be deleted using Lightning data service. See the above code to call below delete method on the delete icon of data row.

     //Deleting selected record id
        deleteRecordById=()=>
        {
            var index = findRowIndexById(this._records, this.recordId);
            if (index !== -1) {
                deleteRecord(this.recordId)
                .then(() => {
                        showMessage(this,'Notification','Record deleted','success');
                        this._records = this._records
                        .slice(0, index)
                        .concat(this._records.slice(index + 1));
                        this.refresh(this._records);
                })
                .catch(error => {
                    showMessage(this,'Notification','Error deleting record','error');
                    console.error(error);
                });
            }      
        }
    

    4. Single Row Selection

    We can restrict single row selection in data table. See our blog Single Row Selection in Lightning Datatable

    5. Sorting on Fields

    Sorting is configurable and each field is sorted on the basis of ascending and descending order of field click.

    handleSortdata(event) {
            this.sortedBy = event.detail.fieldName;
            let fieldValue = row => row[this.sortedBy] || '';
            let reverse = this.sortedDirection === 'asc' ? 1 : -1;
            this.sortedDirection = this.sortedDirection === 'asc'?'desc':'asc';
            this._records = [...this._records.sort(
                (a, b) => (a = fieldValue(a), b = fieldValue(b), reverse * ((a > b) - (b > a)))
            )];
    }

    6. Field data searching

    Searching is configurable and it will show combo box with column list. Searching is done on the basis of field selected and text criteria.

    var result=arrayContainsValue(this.tempRecords,this.searchFieldVal,inp.value);
     console.log('result:' + result);
    if(inp.value==='' || inp.value==undefined)
    {
         result=this.tempRecords;
    }
    this.refresh(result);

    Let see complete Code:

    All apex code is already added on top.

    LWC Code:

    1. Common Library Component

    2. Dialog Box Component to show edit form

    3. Custom Datatable component

    How to use this datatable component

    1. Show data using object Name and Columns

    We are populating records from Contact object and showing id, name fields.

    Html Template:

       <lightning-card title="Generic Datatabel Demo with Object" icon-name="custom:custom63">
        <div style="height: 300px;">
          <c-dynamic-data-table columns={columns} onrowselection={clickMe} 
          object-name='Contact' editable=true can-delete=true show-pagination=true pagination-size='20'></c-dynamic-data-table>
        </div>
      </lightning-card> 

    JS Code:

    const columns = [
        {label: 'Id', fieldName: 'Id', type: 'text',sortable : true},
        {label: 'Name', fieldName: 'Name', type: 'text',sortable : true, editable: true}
    ];
    export default class GenericDataTableTest extends LightningElement {
        columns = columns;
        where='Name=\'Dhanik Sahni\'';
        param = {
            acctid: '0012v00002pK5mfAAC'
        };
        clickMe()
        {
            alert('clickMe');
        }
    }
    SalesforceCodex_GenericDataTable

    2. Show data using Apex method

    We are populating records from apex method getById and showing id, name fields.

    Html Template:

      <lightning-card title="Generic Datatabel with Apex" icon-name="custom:custom63">
        <div style="height: 200px;">
          <c-dynamic-data-table columns={columns}
          apex-name='getById' param={param}></c-dynamic-data-table>
        </div>
      </lightning-card>

    JS Code:

    const columns = [
        {label: 'Id', fieldName: 'Id', type: 'text',sortable : true},
        {label: 'Name', fieldName: 'Name', type: 'text',sortable : true, editable: true}
    ];
    export default class GenericDataTableTest extends LightningElement {
        columns = columns;
    }
    SalesforceCodex Generic Data Table

    3. Show data using records and columns

    We are populating records from array available in component and showing id, name fields.

    Html Template:

      <lightning-card title="Generic Datatabel with Records and Columns" icon-name="custom:custom63">
        <div style="height: 200px;">
          <c-dynamic-data-table columns={columns} records={records}></c-dynamic-data-table>
        </div>
      </lightning-card>

    JS Code:

    import { LightningElement } from 'lwc';
    
    const columns = [
        {label: 'Id', fieldName: 'Id', type: 'text',sortable : true},
        {label: 'Name', fieldName: 'Name', type: 'text',sortable : true, editable: true}
    ];
    export default class GenericDataTableTest extends LightningElement {
        columns = columns;
        records=[
            {
                'Id':'00001',
                'Name':'Dhanik Sahni'
            },
            {
                'Id':'00002',
                'Name':'Hanu Singh'
            },{
                'Id':'00003',
                'Name':'Ram Singh'
            },
        ]
    }
    Salesforcecodex Dynamic Data Table

    References:

    https://developer.salesforce.com/docs/component-library/bundle/lightning-datatable/example

    Other Post for datatable

    Single Row Selection in Lightning Datatable

    Extend lightning-datatable with file upload element in Lightning Web Component

    apex rest icallable lightning lightning component Lightning web component lightning-combobox lightning-datatable lwc lwc dialog box salesforce slot
    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Previous ArticleSingle Row Selection in Lightning Datatable
    Next Article Uploading Files to Microsoft One Drive using Apex
    Dhanik Lal Sahni
    • Website
    • Facebook
    • X (Twitter)

    With over 18 years of experience in web-based application development, I specialize in Salesforce technology and its ecosystem. My journey has equipped me with expertise in a diverse range of technologies including .NET, .NET Core, MS Dynamics CRM, Azure, Oracle, and SQL Server. I am dedicated to staying at the forefront of technological advancements and continuously researching new developments in the Salesforce realm. My focus remains on leveraging technology to create innovative solutions that drive business success.

    Related Posts

    By Dhanik Lal Sahni6 Mins Read

    Top 10 Salesforce Flow Features of Salesforce Summer ’25

    May 11, 2025
    By Dhanik Lal Sahni6 Mins Read

    Unlock the Power of Vibe Coding in Salesforce

    April 30, 2025
    By Dhanik Lal Sahni5 Mins Read

    How to Implement Dynamic Queueable Chaining in Salesforce Apex

    April 21, 2025
    View 7 Comments

    7 Comments

    1. Zakeer on September 30, 2020 11:03 pm

      HI Dhanik,

      Your Custom data table is super but facing some issue , in the pagination of first page selected one row, the same row is selected in other page as well. could you please help me out, how to rectify this issue.

      –
      Thanks,
      Zakeer.

      Reply
      • Dhanik Lal Sahni on October 1, 2020 12:03 am

        Hello Zakeer,

        I have update commonDatatable.html and commonDatatable.js code. Check now with updated code.

        Thank You,
        Dhanik

        Reply
    2. Zakeer on October 2, 2020 10:25 am

      Thanks Dhanik. Still the issue exist. When i selected the first row on the first page, the same row is selected on the other page.

      Please help me on the below point
      1) Selected of rows
      2) restrict the end user, to select only one row
      3) when iam passing the data to the data table, it shows all the data in the first page itself, when i click on the next page , at that time i see 10 records per page.

      Reply
    3. Zakeer on October 2, 2020 10:27 am

      Thanks Dhanik. Still the issue exist. When i selected the first row on the first page, the same row is selected on the other page.

      Please help me on the below point
      1) When i selected the first row on the first page, the same row is selected on the other page.
      2) restrict the end user, to select only one row
      3) when iam passing the data to the data table, it shows all the data in the first page itself, when i click on the next page , at that time i see 10 records per page.

      Reply
    4. Nagaratna on December 2, 2022 2:41 pm

      Sir is there any way to get record count in org by using lwc when selecting object and field whether the field is used in filling the records.

      Reply
      • Dhanik Lal Sahni on December 7, 2022 8:12 pm

        Hello Nagaratna,
        You can use Apex Count() in SOQL to get record count and display in fields. Ping me on linkedin if you need to discuss something related to this topic.

        Thank You,
        Dhanik

        Reply
    5. Pingback: Data Table in Screen Flow - SalesforceCodex

    Leave A Reply Cancel Reply

    Ranked #1 SALESFORCE DEVELOPER BLOG BY SALESFORCEBEN.COM
    Featured on Top Salesforce Developer Blog By ApexHours
    Recent Posts
    • Top 10 Salesforce Flow Features of Salesforce Summer ’25
    • Unlock the Power of Vibe Coding in Salesforce
    • How to Implement Dynamic Queueable Chaining in Salesforce Apex
    • How to Implement Basic Queueable Chaining in Salesforce Apex
    • How to Suppress PMD Warnings in Salesforce Apex
    Ranked in Top Salesforce Blog by feedspot.com
    RSS Recent Stories
    • How to Connect Excel to Salesforce to Manage Your Data and Metadata February 9, 2025
    • Difference Between With Security and Without Security in Apex January 2, 2025
    • Top Reasons to Love Salesforce Trailhead: A Comprehensive Guide December 5, 2024
    • How to Utilize Apex Properties in Salesforce November 3, 2024
    • How to Choose Between SOQL and SOSL Queries July 31, 2024
    Archives
    Categories
    Tags
    apex (110) apex code best practice (8) apex rest (11) apex trigger best practices (4) architecture (22) Asynchronous apex (9) AWS (5) batch apex (9) batch processing (4) code optimization (8) code review tools (3) custom metadata types (5) design principle (9) einstein (3) flow (15) future method (4) google (6) google api (4) integration (19) integration architecture (6) lighting (8) lightning (64) lightning-combobox (5) lightning-datatable (10) lightning component (29) Lightning web component (61) lwc (50) named credential (8) news (4) optimize apex (3) optimize apex code (4) Permission set (4) Queueable (9) rest api (23) S3 Server (4) salesforce (140) salesforce apex (46) salesforce api (4) salesforce api integration (5) Salesforce Interview Question (4) salesforce news (5) salesforce question (5) solid (6) tooling api (5) Winter 20 (8)

    Get our newsletter

    Want the latest from our blog straight to your inbox? Chucks us your detail and get mail when new post is published.
    * indicates required

    Ranked #1 SALESFORCE DEVELOPER BLOG BY SALESFORCEBEN.COM
    Featured on Top Salesforce Developer Blog By ApexHours
    Recent Posts
    • Top 10 Salesforce Flow Features of Salesforce Summer ’25
    • Unlock the Power of Vibe Coding in Salesforce
    • How to Implement Dynamic Queueable Chaining in Salesforce Apex
    • How to Implement Basic Queueable Chaining in Salesforce Apex
    • How to Suppress PMD Warnings in Salesforce Apex
    Ranked in Top Salesforce Blog by feedspot.com
    RSS Recent Stories
    • How to Connect Excel to Salesforce to Manage Your Data and Metadata February 9, 2025
    • Difference Between With Security and Without Security in Apex January 2, 2025
    • Top Reasons to Love Salesforce Trailhead: A Comprehensive Guide December 5, 2024
    • How to Utilize Apex Properties in Salesforce November 3, 2024
    • How to Choose Between SOQL and SOSL Queries July 31, 2024
    Archives
    Categories
    Tags
    apex (110) apex code best practice (8) apex rest (11) apex trigger best practices (4) architecture (22) Asynchronous apex (9) AWS (5) batch apex (9) batch processing (4) code optimization (8) code review tools (3) custom metadata types (5) design principle (9) einstein (3) flow (15) future method (4) google (6) google api (4) integration (19) integration architecture (6) lighting (8) lightning (64) lightning-combobox (5) lightning-datatable (10) lightning component (29) Lightning web component (61) lwc (50) named credential (8) news (4) optimize apex (3) optimize apex code (4) Permission set (4) Queueable (9) rest api (23) S3 Server (4) salesforce (140) salesforce apex (46) salesforce api (4) salesforce api integration (5) Salesforce Interview Question (4) salesforce news (5) salesforce question (5) solid (6) tooling api (5) Winter 20 (8)

    Get our newsletter

    Want the latest from our blog straight to your inbox? Chucks us your detail and get mail when new post is published.
    * indicates required

    Facebook X (Twitter) Instagram Pinterest YouTube Tumblr LinkedIn Reddit Telegram
    © 2025 SalesforceCodex.com. Designed by Vagmine Cloud Solution.

    Type above and press Enter to search. Press Esc to cancel.

    Ad Blocker Enabled!
    Ad Blocker Enabled!
    Our website is made possible by displaying online advertisements to our visitors. Please support us by disabling your Ad Blocker.