December 29, 2020

Re-Usable Custom Table with nested iterator using LWC in Salesforce

Sample Code:

Apex Class:

public with sharing class CustomTableController {
    
    @AuraEnabled( cacheable = true )
    public static List < sObject > fetchRecords( String strRecordId, String strField, String strObjectName, String strColumns ) {
     
        String strSOQL = ' SELECT Id, ' + strColumns + ' FROM ' + strObjectName + ' WHERE ' + strField;
        strSOQL += ' = \'' + strRecordId + '\'';
        system.debug( 'SOQL is ' + strSOQL );
        return Database.query( strSOQL );
         
    }

}

customTableColumn.html:
<template>
    {strValue}
</template>

customTableColumn.js:
import { LightningElement, api } from 'lwc';

export default class CustomTableColumn extends LightningElement {

    @api column;
    @api record;
    strValue

    connectedCallback() {

        this.strValue = this.record[ this.column ];

    }
    
}

customTableColumn.js-meta.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <isExposed>false</isExposed>
</LightningComponentBundle>

customTable.html:
<template>
    <lightning-card>
        <table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_col-bordered">
            <thead>
                <tr>
                    <template for:each={labelsArr} for:item="col">
                        <th key={col}>{col}</th>
                    </template>
                </tr>
            </thead>
            <tbody>
                <template for:each={listRecs} for:item="rec">
                    <tr key={rec.Id}>
                        <template for:each={colsArr} for:item="col">
                            <td key={col}><c-custom-table-column column={col} record={rec}></c-custom-table-column></td>
                        </template>
                    </tr>
                </template>
            </tbody>
        </table>
    </lightning-card>
</template>

customTable.js:
import { LightningElement, api, wire } from 'lwc';
import fetchRecs from '@salesforce/apex/CustomTableController.fetchRecords';

export default class CustomTable extends LightningElement {

    @api recordId;
    @api columns;
    @api field;
    @api objName;
    @api labels;
    colsArr;
    labelsArr;
    listRecs;

    connectedCallback() {
    
        this.colsArr = this.columns.split( "," );
        this.labelsArr = this.labels.split( "," );
        console.log( "Labels are " + JSON.stringify( this.labelsArr ) );

    }

    @wire( fetchRecs, { strRecordId: '$recordId', strField: '$field', strObjectName: '$objName', strColumns: '$columns' } )  
    wiredRec( { error, data } ) {

        if ( data ) {

            console.log( 'Records are ' + JSON.stringify( data ) );
            this.listRecs = data;
            console.log( 'Records are ' + JSON.stringify( this.listRecs ) );

        } else if ( error ) {

            this.listRecs = null;
            this.error = error;

        }
        
    }

}

customTable.js-meta.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordPage">
            <property name="columns" label="Columns" type="String" />
            <property name="field" label="Field" type="String" />
            <property name="objName" label="Object Name" type="String" />
            <property name="labels" label="Labels" type="String" />
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

Output:




No comments:

Post a Comment