This post explains how to add/remove the rows using the Lighting web component(LWC).
HTML Code:
<template>
<lightning-card>
<lightning-spinner if:true={isSpinner} variant="brand" size="large"> </lightning-spinner>
<lightning-layout>
<lightning-layout-item size="12">
<lightning-button class="slds-float--right slds-m-around_small" variant="brand" label="Save"
onclick={saveRows}>
</lightning-button>
<table class="slds-table slds-table_cell-buffer slds-table_bordered slds-border_left slds-border_right"
aria-labelledby="element-with-table-label other-element-with-table-label">
<thead>
<tr>
<th>Name</th>
<th>Industry</th>
<th>Phone</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody>
<template for:each={filterList} for:item="filterData" for:index="index">
<tr key={filterData}>
<td>
<lightning-input type="text" name="accName" data-index={index}
variant="label-hidden" placeholder="" onchange={handleChange}
value={filterData.Name}>
</lightning-input>
</td>
<td>
<lightning-combobox name="industry" data-index={index} variant="label-hidden"
placeholder="" onchange={handleChange} value={filterData.Industry}
options={industryOptions}>
</lightning-combobox>
</td>
<td>
<lightning-input type="text" name="accEmail" data-index={index}
variant="label-hidden" placeholder="" onchange={handleChange}
value={filterData.Email}>
</lightning-input>
</td>
<td>
<lightning-input type="text" name="accPhone" data-index={index}
value={filterData.Phone} variant="label-hidden" onchange={handleChange}>
</lightning-input>
</td>
<td>
<lightning-button-icon data-index={filterData.id} class="slds-float--right"
icon-name="action:new" onclick={handleAddRow}></lightning-button-icon>
<lightning-button-icon data-index={filterData.id} class="slds-float--right"
icon-name="action:delete" onclick={handleRemoveRow}></lightning-button-icon>
</td>
</tr>
</template>
</tbody>
</table>
</lightning-layout-item>
</lightning-layout>
</lightning-card>
</template>
JS Code:import { LightningElement, wire } from 'lwc';
import { getPicklistValues } from 'lightning/uiObjectInfoApi';
import { getObjectInfo } from 'lightning/uiObjectInfoApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import saveAccounts from '@salesforce/apex/LWCExampleController.saveAccounts';
export default class DynamicallyAddRow extends LightningElement {
industryOptions = [{ value: '-None-', label: '' }];
filterList = [];
keyIndex = 0;
isSpinner = false;
@wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
accountinfo;
@wire(getPicklistValues, { recordTypeId: '$accountinfo.data.defaultRecordTypeId', fieldApiName: INDUSTRY_FIELD })
industryValues({ data, error }) {
if (data) {
data.values.forEach(val => {
this.industryOptions = [...this.industryOptions, { value: val.value, label: val.label }];
});
}
else if (error) {
this.processErrorMessage(error);
}
}
connectedCallback() {
this.handleAddRow();
}
handleChange(event) {
if (event.target.name == 'accName') {
this.filterList[event.currentTarget.dataset.index].Name = event.target.value;
}
else if (event.target.name == 'industry') {
this.filterList[event.currentTarget.dataset.index].Industry = event.target.value;
}
else if (event.target.name == 'accEmail') {
this.filterList[event.currentTarget.dataset.index].Email = event.target.value;
}
else if (event.target.name == 'accPhone') {
this.filterList[event.currentTarget.dataset.index].Phone = event.target.value;
}
}
handleAddRow() {
let objRow = {
Name: '',
Industry: '',
Phone: '',
Email: '',
id: ++this.keyIndex
}
this.filterList = [...this.filterList, Object.create(objRow)];
}
handleRemoveRow(event) {
this.filterList = this.filterList.filter((ele) => {
return parseInt(ele.id) !== parseInt(event.currentTarget.dataset.index);
});
if (this.filterList.length == 0) {
this.handleAddRow();
}
}
saveRows() {
console.log('this.filterList => ', this.filterList);
this.isSpinner = true;
saveAccounts({ lstAccs: this.filterList }).then(result => {
this.isSpinner = false;
this.showToastMessage('success', 'Accounts Saved Successfully!!', 'Success');
this.filterList = [];
if (this.filterList.length == 0) {
this.handleAddRow();
}
console.log('result ==> ', result);
}).catch(error => {
this.processErrorMessage(error);
this.isSpinner = false;
})
}
processErrorMessage(message) {
let errorMsg = '';
if (message) {
if (message.body) {
if (Array.isArray(message.body)) {
errorMsg = message.body.map(e => e.message).join(', ');
} else if (typeof message.body.message === 'string') {
errorMsg = message.body.message;
}
}
else {
errorMsg = message;
}
}
this.showToastMessage('error', errorMsg, 'Error!');
}
showToastMessage(variant, message, title) {
this.dispatchEvent(
new ShowToastEvent({
title: title,
message: message,
variant: variant
})
);
}
}
Apex Class:
public inherited sharing class LWCExampleController {
@AuraEnabled
public static List<Account> saveAccounts(List<Account> lstAccs) {
try {
insert lstAccs;
return lstAccs;
}
catch(Exception ex) {
throw new AuraHandledException(ex.getMessage());
}
}
}
Output: