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>
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>