Tuesday, May 12, 2020

Adding and removing rows to a custom table using lightning web component

below example illustrates how can we add new row to a lightning table and how can we delete a table row, and how can we save table.

createComponentReq.html

<template>  
    <div class="slds-m-around--xx-large container-fluid">
        <div class="slds-float_right slds-p-bottom_small">
            <lightning-button label="Add" onclick={addRow} icon-name="utility:add"></lightning-button>
        </div>
        <div class="container-fluid">
            <table class="slds-table slds-table_bordered slds-table_cell-buffer">
                <thead>
                    <tr class="slds-text-title_caps">
                        <th scope="col">
                            <div class="slds-truncate">#</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Field Label">Field Label</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Field API Name">Field API Name</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Field Data Type">Field Data Type</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Object Name">Object Name</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Object Relation">Object Relation</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Action">Action</div>
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <template for:each={RequestList} for:item="req" for:index="indx">
                        <tr key={req.key} id={req.key}>
                            <td>{indx}</td>
                            <td>
                                <lightning-input data-id={indx} label="Field Label" value={req.Label}
                                    onblur={handleLabelChange}></lightning-input>
                            </td>
                            <td>
                                <lightning-input data-id={indx} label="Field Api Name" value={req.ApiName}
                                    onblur={handleApiChange}></lightning-input>
                            </td>
                            <td>
                                <lightning-combobox data-id={indx} label="Field Data Type" value={req.DataType}
                                    placeholder="-Select-" options={DataTypePicklistValues.data.values}
                                    onblur={handleDataTypeChange}>
                                </lightning-combobox>
                                <!--
                                <lightning-input data-id={indx} label="Field Data Type" value={req.DataType}
                                    onchange={handleDataTypeChange}></lightning-input> -->
                            </td>
                            <td>
                                <lightning-input data-id={indx} label="Object Api Name" value={req.ObjectName}
                                    onblur={handleObjectNameChange}></lightning-input>
                            </td>
                            <td>
                                <lightning-input data-id={indx} label="Object Relation" value={req.ObjectRelation}
                                    onblur={handleObjectRelationChange}></lightning-input>
                            </td>
                            <td>
                                <lightning-button-icon icon-name="utility:delete" data-id={indx}
                                    alternative-text="Delete" class="slds-m-left_xx-small" onclick={removeRow}
                                    title="Delete"></lightning-button-icon>
                            </td>
                        </tr>
                    </template>
                </tbody>
            </table>
            <div class="slds-align_absolute-center slds-p-top_small">
                <lightning-button name="Save" label="Generate Component" onclick={saveRecord}></lightning-button>
            </div>
        </div>
    </div>
</template>


createComponentReq.js

import { LightningElement, track, api, wire } from 'lwc';
import { getPicklistValues } from 'lightning/uiObjectInfoApi';
import { getObjectInfo } from 'lightning/uiObjectInfoApi';
import REQUEST_OBJECT from '@salesforce/schema/Dynamic_Request__c';
import LABEL_FIELD from '@salesforce/schema/Dynamic_Request__c.Field_Label__c';
import API_FIELD from '@salesforce/schema/Dynamic_Request__c.Field_Api_Name__c';
import DATATYPE_FIELD from '@salesforce/schema/Dynamic_Request__c.Field_Data_Type__c';
import OBJECT_FIELD from '@salesforce/schema/Dynamic_Request__c.Object_Name__c';
import OBJECTRELATION_FIELD from '@salesforce/schema/Dynamic_Request__c.Object_Relationship__c';
import saveRequests from '@salesforce/apex/RequestController.saveRequests';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class CreateDynamicRecord extends LightningElement {
    @track RequestList = [];
    @track index = 0;
    @track label = LABEL_FIELD;
    @track apiName = API_FIELD;
    @track dataType = DATATYPE_FIELD;
    @track objectName = OBJECT_FIELD;
    @track objectRelation = OBJECTRELATION_FIELD;

    @api req = {
        Label: this.label,
        ApiName: this.apiName,
        DataType: this.dataType,
        ObjectName: this.objectName,
        ObjectRelation: this.objectRelation,
        key: ''
    }

    @wire(getObjectInfo, { objectApiName: REQUEST_OBJECT })
    objectInfo;

    @wire(getPicklistValues, { recordTypeId: '$objectInfo.data.defaultRecordTypeId', fieldApiName: DATATYPE_FIELD})
    DataTypePicklistValues;

    addRow() {
        this.index++;
        var i = this.index;
        this.req.key = i;
        this.RequestList.push(JSON.parse(JSON.stringify(this.req)));
   

    removeRow(event) {
        var selectedRow = event.currentTarget;
        var key = selectedRow.dataset.id;
        if (this.RequestList.length > 1) {
            this.RequestList.splice(key, 1);
            this.index--;
        } else if (this.RequestList.length == 1) {
            this.RequestList = [];
            this.index = 0;
        }
    }

    handleLabelChange(event) {
        var selectedRow = event.currentTarget;
        var key = selectedRow.dataset.id;
        this.RequestList[key].Label = event.target.value;
    }

    handleApiChange(event) {
        var selectedRow = event.currentTarget;
        var key = selectedRow.dataset.id;
        this.RequestList[key].ApiName = event.target.value;
    }

    handleDataTypeChange(event){
        var selectedRow = event.currentTarget;
        var key = selectedRow.dataset.id;
        this.RequestList[key].DataType = event.target.value;
    }

    handleObjectNameChange(event){
        var selectedRow = event.currentTarget;
        var key = selectedRow.dataset.id;
        this.RequestList[key].ObjectName = event.target.value;
    }

    handleObjectRelationChange(event){
        var selectedRow = event.currentTarget;
        var key = selectedRow.dataset.id;
        this.RequestList[key].ObjectRelation = event.target.value;
    }   

    saveRecord() {
        console.log('RequestList--->>'+JSON.stringify(this.RequestList));
        saveRequests({ reqList: this.RequestList })
            .then(result => {
                this.message = result;
                this.error = undefined;
                if (this.message !== undefined) {
                    this.req.Lable = '';
                    this.req.ApiName = '';
                    this.req.DataType = '';
                    this.req.ObjectName = '';
                    this.req.ObjectRelation = '';
                    this.dispatchEvent(
                        new ShowToastEvent({
                            title: 'Success',
                            message: 'Request created successfully',
                            variant: 'success',
                        }),
                    );
                }
                console.log('res-->'+JSON.stringify(result));
                console.log("result", this.message);
            })
            .catch(error => {
                this.message = undefined;
                this.error = error;
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Error creating record',
                        message: error.body.message,
                        variant: 'error',
                    }),
                );
                console.log("error", JSON.stringify(this.error));
            });
    }
}


createComponentReq.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>