lightning datatable inline editing using LWC in Salesforce
This blog will help for Lightning data table inLine Editing and update record by uiRecordAPI. So we fetch the number of contacts from Account and display in LWC datatable.
draftValues store the edited values and after click on save these values save in relevant records. for InLine Edit each column should be editable: true
ContactsFromAccount.cls
public without sharing class ContactsFromAccount {
@AuraEnabled (Cacheable = true)
public static List<Contact> getContactList(String accId){
List<Contact> conList = new List<Contact>();
try {
conList = [Select Id, FirstName, LastName , Title, Email from Contact where AccountId =: accId ];
} catch (Exception e) {
throw new AuraHandledException(e.getMessage());
}
return conList;
}
}
contactsFromAccount.html
<template>
<lightning-card title="Datatable With InLine Edit" icon-name="custom:custom63">
<div class="slds-m-around_medium">
<lightning-datatable
key-field="Id"
data={contactList.data}
columns={columns}
onsave={handleSave}
draft-values={draftValues}>
hide-checkbox-column
show-row-number-column>
</lightning-datatable>
</div>
</lightning-card>
</template>
contactsFromAccount.js
import { LightningElement,api, wire } from 'lwc';
import { updateRecord } from 'lightning/uiRecordApi';
import {refreshApex} from '@salesforce/apex';
import {ShowToastEvent} from 'lightning/platformShowToastEvent'
import getContacts from '@salesforce/apex/ContactsFromAccount.getContactList';
import FIRSTNAME_FIELD from '@salesforce/schema/Contact.FirstName';
import LASTNAME_FIELD from '@salesforce/schema/Contact.LastName';
import TITLE_FIELD from '@salesforce/schema/Contact.Title';
import PHONE_FIELD from '@salesforce/schema/Contact.Phone';
import EMAIL_FIELD from '@salesforce/schema/Contact.Email';
const COLS = [
{
label: 'First Name',
fieldName: FIRSTNAME_FIELD.fieldApiName,
type: 'text',
editable: true
},
{
label: 'Last Name',
fieldName: LASTNAME_FIELD.fieldApiName,
type: 'text',
editable: true
},
{ label: 'Title',
fieldName: TITLE_FIELD.fieldApiName,
type: 'text',
editable: true
},
{
label: 'Phone',
fieldName: PHONE_FIELD.fieldApiName,
type: 'phone',
editable: true
},
{
label: 'Email',
fieldName: EMAIL_FIELD.fieldApiName,
type: 'email',
editable: true
}
];
export default class ContactsFromAccount extends LightningElement {
@api recordId;
columns = COLS;
contactList=[];
draftValues = [];
error;
@wire(getContacts,{accId : '$recordId'}) contacts(result){
if(result.data){
this.contactList = result;
}else if(result.error){
console.log('ERROR ==>> '+error);
this.error = result.error;
this.contactList = [];
}
}
handleSave(event){
// Convert datatable draft values into record objects
const inputsItems = event.detail.draftValues.slice().map((draftValue) => {
const fields = Object.assign({}, draftValue);
return { fields };
});
// Clear all datatable draft values
this.draftValues = [];
// Update all records in parallel thanks to the UI API
const recordUpdate = inputsItems.map((recordInput) => updateRecord(recordInput));
Promise.all(recordUpdate).then(res => {
this.dispatchEvent(
new ShowToastEvent({
title: 'Success',
message: 'Records Updated Successfully!!',
variant: 'success'
})
);
return this.refresh();
}).catch(error => {
this.dispatchEvent(
new ShowToastEvent({
title: 'Error',
message: 'An Error Occured!!',
variant: 'error'
})
);
}).finally(() => {
});
}
async refresh(){
await refreshApex(this.contactList);
}
}
contactsFromAccount.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>55.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__RecordPage</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__RecordPage">
<objects>
<object>Account</object>
</objects>
</targetConfig>
</targetConfigs>
</LightningComponentBundle>
this component only available for Account record page, because we have mentioned as in meta.xml