Inline Editing in lightning-datatable in LWC Salesforce

by Rijwan Mohmmed
7 comments
Inline Editing in lightning-datatable in LWC Salesforce

Hello friends, today we will discuss Inline Editing in lightning-datatable in LWC Salesforce.

Salesforce data can be displayed in a table using the lightning-datatable component. By using inline editing, users can update field values without navigating to the record.  

Also check this: Display Maps in Lightning Web Component Salesforce

inline-editing-in-lightning-datatable-in-lwc-salesforce-techdicer
inline-editing-in-lightning-datatable-in-lwc-salesforce-techdicer

Key Highlights :

  1. update record with navigate.
  2. update records without calling apex and DML operation.

Code:

LWCInlineCtrl.cls:

public class LWCInlineCtrl {
    @AuraEnabled(Cacheable = true)
    public static List<Contact> getContacts() {
        return [SELECT Id, Name, FirstName, LastName, Phone, Email 
                FROM Contact 
                WHERE Email != null 
                AND Phone != null 
                ORDER BY CreatedDate limit 20];
    }
}

LWCInline.HTML :

<template>

     <!------Header------->
    <div class="slds-tabs_card">
		<div class="slds-page-header">
			<div class="slds-page-header__row">
				<div class="slds-page-header__col-title">
					<div class="slds-media">
						<div class="slds-media__figure">
							<span class="slds-icon_container slds-icon-standard-opportunity">
								 <lightning-icon icon-name="standard:recipe" alternative-text="recipe" title="recipe"></lightning-icon>
                            </span>
						</div>
						<div class="slds-media__body">
							<div class="slds-page-header__name">
								<div class="slds-page-header__name-title">
									<h1>
										<span>Inline Editing in lightning-datatable in LWC Salesforce </span>
										<span class="slds-page-header__title slds-truncate" title="Recently Viewed">TechDicer</span>
									</h1>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div> <br/>
    <!------/Header------->


    <lightning-card title="Inline Editing in lightning-datatable in LWC Salesforce" icon-name="standard:contact">
        <template if:true={contacts.data}>
            <lightning-datatable key-field="Id" 
                                 data={contacts.data} 
                                 columns={columns} 
                                 onsave={handleSave}
                                 draft-values={saveDraftValues} 
                                 hide-checkbox-column 
                                 show-row-number-column>
            </lightning-datatable>
        </template>
    </lightning-card>
</template>

LWCInline.JS:

import { LightningElement, wire, track } from 'lwc';
import getContacts from '@salesforce/apex/LWCInlineCtrl.getContacts';
import { updateRecord } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { refreshApex } from '@salesforce/apex';

// columns
const columns = [
    {
        label: 'Name',
        fieldName: 'Name',
        type: 'text',
    }, {
        label: 'FirstName',
        fieldName: 'FirstName',
        type: 'text',
        editable: true,
    }, {
        label: 'LastName',
        fieldName: 'LastName',
        type: 'text',
        editable: true,
    }, {
        label: 'Phone',
        fieldName: 'Phone',
        type: 'phone',
        editable: true
    }
];

export default class LWCInline extends LightningElement {
    columns = columns;
    @track contacts;
    saveDraftValues = [];

    @wire(getContacts)
    contactData(result) {
        this.contacts = result;
        if (result.error) {
            this.contacts = undefined;
        }
    };

    handleSave(event) {
        this.saveDraftValues = event.detail.draftValues;
        const recordInputs = this.saveDraftValues.slice().map(draft => {
            const fields = Object.assign({}, draft);
            return { fields };
        });

        // Updateing the records using the UiRecordAPi
        const promises = recordInputs.map(recordInput => updateRecord(recordInput));
        Promise.all(promises).then(res => {
            this.ShowToast('Success', 'Records Updated Successfully!', 'success', 'dismissable');
            this.saveDraftValues = [];
            return this.refresh();
        }).catch(error => {
            this.ShowToast('Error', 'An Error Occured!!', 'error', 'dismissable');
        }).finally(() => {
            this.saveDraftValues = [];
        });
    }

    ShowToast(title, message, variant, mode){
        const evt = new ShowToastEvent({
                title: title,
                message:message,
                variant: variant,
                mode: mode
            });
            this.dispatchEvent(evt);
    }

    // This function is used to refresh the table once data updated
    async refresh() {
        await refreshApex(this.contacts);
    }
}

Output:

inline-editing-in-lightning-datatable-in-lwc-salesforce-techdicer
inline-editing-in-lightning-datatable-in-lwc-salesforce-techdicer

Reference :

  1. Display Data in a Table with Inline Editing
What’s your Reaction?
+1
10
+1
4
+1
2
+1
2
+1
4
+1
1

You may also like

7 comments

Goverdhan January 22, 2023 - 7:02 am

Thank you very much for this very valuable knowledge that you have shared !

Reply
ravi August 9, 2023 - 6:40 am

how to show pencil icon always to the right side of column

Reply
Rijwan Mohmmed August 9, 2023 - 6:42 am

Hi @Ravi
currently pencil icon not showing in right side ??

Reply
Amit October 23, 2023 - 1:18 pm

Refrece is not working

Js—>

import { LightningElement, wire, track, api } from ‘lwc’;
import getTheRemarksRecommendationsData from ‘@salesforce/apex/PNB_Los_NoteTracker_Controller.getRemarksRecommendationsData’;
import getTheQueryData from ‘@salesforce/apex/PNB_Los_NoteTracker_Controller.getQueryData’;
import { updateRecord } from ‘lightning/uiRecordApi’;
import { ShowToastEvent } from ‘lightning/platformShowToastEvent’;
import { refreshApex } from ‘@salesforce/apex’;

const RCCOLUMNS = [
//{ label: ‘No.’, fieldName: ‘rowNumber’, type: ‘number’, sortable: “true”, initialWidth: 70 },
{ label: ‘Name’, fieldName: ‘nameLink’, sortable: “true”, type: ‘url’, typeAttributes: { label: { fieldName: ‘Name’ }, target: ‘_blank’ } },
{ label: ‘Related Module’, fieldName: ‘Object_Name__c’, type: ‘text’ },
{ label: ‘Recommendation’, fieldName: ‘Recommendation__c’, sortable: “true”, editable: true },
{ label: ‘Remarks’, fieldName: ‘Remarks__c’, type: ‘text’, sortable: “true”, editable: true },
{ label: ‘Created By’, fieldName: ‘CreatedBy’, sortable: “true” },
{ label: ‘Created Date’, fieldName: ‘CreatedDate’, type: ‘date’, typeAttributes: { day: ‘numeric’, month: ‘short’, year: ‘numeric’, hour: ‘2-digit’, minute: ‘2-digit’, second: ‘2-digit’, hour12: true }, sortable: “true” },
]
const QCOLUMNS = [
//{ label: ‘No.’, fieldName: ‘rowNumber’, type: ‘number’, sortable: “true”, initialWidth: 70 },
{ label: ‘Name’, fieldName: ‘nameLink’, sortable: “true”, type: ‘url’, typeAttributes: { label: { fieldName: ‘Name’ }, target: ‘_blank’ } },
{ label: ‘Created By’, fieldName: ‘CreatedBy’, sortable: “true” },
{ label: ‘Created Date’, fieldName: ‘CreatedDate’, type: ‘date’, typeAttributes: { day: ‘numeric’, month: ‘short’, year: ‘numeric’, hour: ‘2-digit’, minute: ‘2-digit’, second: ‘2-digit’, hour12: true }, sortable: “true” },
{ label: ‘Response’, fieldName: ‘Response__c’, type: ‘text’, sortable: “true”, editable: true },
]

export default class PnbLosNotesTracker extends LightningElement {
NotesTrakerScreen = true;
rCol = RCCOLUMNS;
qCol = QCOLUMNS;
lstRemarksRecommendationsData;
lstQueriesData;
saveDraftValues = [];
@api recordId;
@track error;

// For Remarks & Recommendations DataTable
@wire(getTheRemarksRecommendationsData, { lafId: ‘$recordId’ })
RemarkHandler({ data, error }) {
if (data) {
let result = JSON.parse(JSON.stringify(data));
console.log(‘Remarks & Recommendations-result==> ‘ + JSON.stringify(result));
result = result.map(row => {
return {
…row,
nameLink: `/lightning/r/${row.Id}/view`,
//Name: ( row.Name ? row.Name : null ),
CreatedBy: (row.CreatedBy ? row.CreatedBy.Name : null),
};
})
this.lstRemarksRecommendationsData = result;
this.error = undefined;
}
else if (error) {
this.error = error;
this.lstRemarksRecommendationsData = undefined;
console.error(error)

}
}
// For Quary DataTable
@wire(getTheQueryData, { lafId: ‘$recordId’ })
quaryHandler({ data, error }) {
if (data) {
let result = JSON.parse(JSON.stringify(data));
console.log(‘Query==> ‘ + JSON.stringify(result));
result = result.map(row => {
return {
…row,
nameLink: `/lightning/r/${row.Id}/view`,
//Name: ( row.Name ? row.Name : null ),
CreatedBy: (row.CreatedBy ? row.CreatedBy.Name : null),
};
})
this.lstQueriesData = result;
this.error = undefined;
}
else if (error) {
this.error = error;
this.lstQueriesData = undefined;
console.error(error)

}
}

handleSave(event) {
this.saveDraftValues = event.detail.draftValues;
const recordInputs = this.saveDraftValues.slice().map(draft => {
const fields = Object.assign({}, draft);
return { fields };
});

// Updateing the records using the UiRecordAPi
const promises = recordInputs.map(recordInput => updateRecord(recordInput));
Promise.all(promises).then(res => {
this.ShowToast(‘Success’, ‘Records Updated Successfully!’, ‘success’, ‘dismissable’);
this.saveDraftValues = [];
return this.refresh();
}).catch(error => {
this.ShowToast(‘Error’, ‘An Error Occured!!’, ‘error’, ‘dismissable’);
}).finally(() => {
this.saveDraftValues = [];
});
}

ShowToast(title, message, variant, mode){
const evt = new ShowToastEvent({
title: title,
message:message,
variant: variant,
mode: mode
});
this.dispatchEvent(evt);
}

// This function is used to refresh the table once data updated
async refresh() {
await refreshApex(this.lstRemarksRecommendationsData);
// await refreshApex(this.lstQueriesData);
}

}

Reply
Rijwan Mohmmed October 23, 2023 - 1:35 pm

You didn’t write correct code for refresh apex variable

Reply
Amit October 25, 2023 - 3:34 am

please correct me.

Reply
Rijwan Mohmmed October 25, 2023 - 4:24 pm

Please schedule a meeting by click below link
https://topmate.io/rijwan_mohmmed

Reply

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.