In below example I’m adding account record in Salesforce Lightning Component with Add Delete Rows functionality.
Apex Class:
public with sharing class AuraSampleController{
@AuraEnabled
public static void saveAccounts(List<Account> accList){
Insert accList;
}
}
Lightning Component:
<aura:component controller="AuraSampleController" Implements="flexipage:availableForRecordHome,force:hasRecordId">
<aura:attribute name="accountList" type="Account[]"/>
<div class="slds-m-around--xx-large">
<div class="slds-float_right slds-p-bottom_small">
<h1 class="slds-page-header__title">Add Row
<lightning:buttonIcon iconName="utility:add" size="large" variant="bare" alternativeText="Add" onclick="{!c.addRow}"/>
</h1>
</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="Account Name">Account Name</div>
</th>
<th scope="col">
<div class="slds-truncate" title="Account Number">Account Number</div>
</th>
<th scope="col">
<div class="slds-truncate" title="Phone">Phone</div>
</th>
<th scope="col">
<div class="slds-truncate" title="Action">Action</div>
</th>
</tr>
</thead>
<tbody>
<aura:iteration items="{!v.accountList}" var="acc" indexVar="index">
<tr>
<td>
{!index + 1}
</td>
<td>
<lightning:input name="accName" type="text" required="true" maxlength="50" label="Account Name" value="{!acc.Name}" />
</td>
<td>
<lightning:input name="accNumber" type="text" maxlength="10" label="Account Number" value="{!acc.AccountNumber}" />
</td>
<td>
<lightning:input name="accPhone" type="phone" maxlength="10" label="Phone" value="{!acc.Phone}" />
</td>
<td>
<a onclick="{!c.removeRow}" data-record="{!index}">
<lightning:icon iconName="utility:delete" size="small" alternativeText="Delete"/>
<span class="slds-assistive-text">Delete</span>
</a>
</td>
</tr>
</aura:iteration>
</tbody>
</table>
<div class="slds-align_absolute-center slds-p-top_small">
<lightning:button variant="brand" label="Submit" title="Brand action" onclick="{!c.save}" />
</div>
</div>
</div>
</aura:component>
Lightning JS Controller:
({
addRow: function(component, event, helper) {
helper.addAccountRecord(component, event);
},
removeRow: function(component, event, helper) {
//Get the account list
var accountList = component.get("v.accountList");
//Get the target object
var selectedItem = event.currentTarget;
//Get the selected item index
var index = selectedItem.dataset.record;
accountList.splice(index, 1);
component.set("v.accountList", accountList);
},
save: function(component, event, helper) {
if (helper.validateAccountList(component, event)) {
helper.saveAccountList(component, event);
}
},
})
Lightning JS Helper:
({
addAccountRecord: function(component, event) {
//get the account List from component
var accountList = component.get("v.accountList");
//Add New Account Record
accountList.push({
'sobjectType': 'Account',
'Name': '',
'AccountNumber': '',
'Phone': ''
});
component.set("v.accountList", accountList);
},
validateAccountList: function(component, event) {
//Validate all account records
var isValid = true;
var accountList = component.get("v.accountList");
for (var i = 0; i < accountList.length; i++) {
if (accountList[i].Name == '') {
isValid = false;
alert('Account Name cannot be blank on row number ' + (i + 1));
}
}
return isValid;
},
saveAccountList: function(component, event, helper) {
//Call Apex class and pass account list parameters
var action = component.get("c.saveAccounts");
action.setParams({
"accList": component.get("v.accountList")
});
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
component.set("v.accountList", []);
alert('Account records saved successfully');
}
});
$A.enqueueAction(action);
},
})
Create Account Record :
Created Account Records :