Salesforce provides a robust platform for managing data and automating business processes, but there are certain limitations when it comes to inline editing of picklist fields. Out of the box, Salesforce does not support inline editing for picklist fields in standard Lightning components like the lightning-data table. However, with some creativity and development skills, you can implement workarounds to achieve inline editing for picklist fields. This blog post will explore a workaround to make this happen.
Understanding the Challenge
Before we dive into the solution, let's understand why inline editing for picklist fields is a challenge. Picklist fields have predefined values, and changing these values requires a dropdown or combo box to select the new option. Standard Salesforce Lightning components do not provide native support for this behaviour in tables or lists.
Custom Picklist Editing in Lightning Datatable
In Salesforce Lightning, the standard Lightning Datatable component provides inline editing for various field types, but it lacks native support for picklist field editing. To overcome this limitation, a custom solution is implemented by extending the Lightning Datatable component and creating a custom picklist editing mechanism. Let's break down the implementation step by step:
1. Extending Lightning Datatable
First, we extend the Lightning Datatable component to create a custom component called LWCCustomDatatable. This custom component allows us to define and use custom cell types, including a custom picklist cell for editing.
import LightningDatatable from 'lightning/datatable';
import picklistColumn from './picklistColumn.html';
import pickliststatic from './pickliststatic.html';
export default class LWCCustomDatatable extends LightningDatatable {
static customTypes = {
picklistColumn: {
template: pickliststatic,
editTemplate: picklistColumn,
standardCellLayout: true,
typeAttributes: ['label', 'placeholder', 'options', 'value', 'context', 'variant', 'name']
}
};
}
2. Custom Picklist Editing Template
To achieve custom picklist editing, we create two custom HTML templates: picklistColumn.html and pickliststatic.html. These templates define how the picklist cell should be displayed in both edit mode and view mode.
picklistColumn.html defines the picklist cell for editing. It includes a Lightning Combobox component that allows users to select a picklist value.
<template>
<lightning-combobox name="picklist" data-inputable="true"
label={typeAttributes.label} value={editedValue}
placeholder={typeAttributes.placeholder}
options={typeAttributes.options} variant='label-hidden'
dropdown-alignment="auto">
</lightning-combobox>
</template>
pickliststatic.html defines the picklist cell in view mode, displaying the selected picklist value.
<template>
<span class="slds-truncate" title={value}>{value}</span>
</template>
3. Implementing Custom Picklist Editing
Within the custom component LWCCustomDatatable, we define the picklistColumn as a custom type and specify its attributes. These attributes include label, placeholder, options, value, context, variant, and name, which are used to configure and control the picklist cell's behaviour.
4. Usage in Lightning Component
In your Lightning component, you can use the LWCCustomDatatable component by specifying the custom type as picklistColumn for the picklist field within your Lightning Datatable. This allows users to edit picklist fields seamlessly within the Datatable.
<c-l-w-c-custom-datatable class="myTable" key-field="Id"
data={visibleRecords} columns={columns} onsave={handleInlineEditSave}
onvalueselect={handleSelection} draft-values={draftValues}
oncellchange={handleCellChange}>
</c-l-w-c-custom-datatable-type>
5. Achieving Custom Picklist Editing
When the Datatable is in edit mode and a picklist cell is selected for editing, the custom picklist editing template (picklistColumn.html) is used, allowing users to select a new picklist value. The changes are then saved, and the custom handling (handleInlineEditSave) updates the records accordingly.
In view mode, the custom picklist static template (pickliststatic.html) displays the selected picklist value.
Configuring Picklist Column
The COLS constant defines column settings for a Lightning data table. In this example, the "Lead Status" column is configured as editable and of type "picklistColumn." This means users can edit the status using a picklist, and the available options are determined by the pickListOptions field. The value and context of the picklist are tied to the "Type" and "Id" fields, respectively.
Fetching Object Information and Picklist Values
In Salesforce, it's crucial to have access to object information and picklist values when working with custom components or interfaces. Here, we use the imperative method to achieve this.
connectedCallback() {
getLeadStatusPicklistValues()
.then(result => {
this.pickListOptions = result.map(item => ({
label: item.label,
value: item.value
}));
})
.catch(error => {
this.createAndDispatchToast (this.customErrorTitle, this.customErrorMessage
, this.customErrorVariant);
});
}
Updating Draft Values
Now, let's explore the updateDraftValues method. This method plays a crucial role in managing and tracking changes made to the draft (unsaved) values in the Lightning data table. It ensures that the changes are properly reflected and followed.
this.createAndDispatchToast(this.customErrorTitle, this.customErrorMessage, this.customErrorVariant);
updateDraftValues(updateItem) {
let draftValueChanged = false;
let copyDraftValues = [...this.draftValues];
copyDraftValues.forEach(item => {
if (item.Id === updateItem.Id) {
for (let field in updateItem) {
item[field] = updateItem[field];
}
draftValueChanged = true;
}
});
if (draftValueChanged) {
this.draftValues = [...copyDraftValues];
} else {
this.draftValues = [...copyDraftValues, updateItem];
}
}
It receives an updateItem object, which typically represents the changes made to a record in the data table.
It creates a copy of the current draftValues array to prevent direct mutations.
It iterates through the copy of draftValues to find the item that matches the ID of the updateItem.
If a matching item is found, it updates the fields in that item with the new values from updateItem.
If no matching item is found, it adds the updateItem to the draftValues array.
The draftValueChanged flag is used to track whether changes were made, and if so, it updates the draftValues array accordingly.
Handling Cell Changes
Within our listPage Lightning component, we have a method called handleCellChange. This method plays a crucial role in managing changes made to cell values within the data table. When a user makes changes to a cell, such as modifying the phone number or email address, these changes are captured in the draftValues array.
The handleCellChange method iterates through the draftValues array and ensures that the changes are properly tracked and reflected in the UI. It calls the updateDraftValues method to update the draftValues array, which represents the pending changes that need to be saved.
handleCellChange(event) {
let draftValues = event.detail.draftValues;
draftValues.forEach(element => {
this.updateDraftValues(element);
});
}
Dropdown Style Toggle
To make the picklist editing feature user-friendly, we implement a dropdown-style toggle mechanism. The toggleDropdown method controls the visibility of the picklist dropdown when a user clicks to edit the picklist value. The dropdownVisible attribute is used to determine whether the dropdown should be displayed or hidden.
toggleDropdown() {
this.dropdownVisible = !this.dropdownVisible;
}
Handling Option Selection
When a user clicks to edit a picklist value, a dropdown list of options should appear. The handleOptionSelect method is responsible for handling the selection of picklist options. It captures the selected value and manages the display of the dropdown accordingly.
handleOptionSelect(event) {
const selectedValue = event.currentTarget.dataset.value;
this.selectedList = selectedValue;
this.toggleDropdown();
}
Updating and Reloading Leads
The heart of this custom picklist editing solution is the handleInlineEditSave method. This method is responsible for updating the changed values in the records and then refreshing the datatable to reflect the changes.
Here's a high-level overview of how it works:
It extracts the changes from draftValues and prepares them for updating records.
It uses lightning/uiRecordApi to update the records asynchronously.
If the updates are successful, it displays a success message using
If the updates are successful, it displays a success message using lightning/platformShowToastEvent.
Finally, it calls refreshApex to refresh the data in the datatable, ensuring that the latest values are displayed.
async handleInlineEditSave(event) {
const draftValues = event.detail.draftValues;
if (draftValues.length === 0) {
return;
}
const records = draftValues.map(draftValue => ({ fields: {
...draftValue } }));
this.draftValues = [];
try {
const recordUpdatePromises = records.map((record) =>
updateRecord(record)
);
await Promise.all(recordUpdatePromises);
const title = CUSTOM_SUCCESS_TITLE_LABEL;
const message = CUSTOM_SUCCESS_MESSAGE_LABEL;
const variant = CUSTOM_SUCCESS_VARIANT_LABEL;
this.createAndDispatchToast(title, message, variant);
refreshApex(this.wiredLeadsResult);
} catch (error) {
this.createAndDispatchToast(this.customErrorTitle,
this.customErrorMessage, this.customErrorVariant);
}
}
Apex Controller and Data Retrieval
To populate the datatable and save changes, you'll need an Apex controller. In this example, we have an Apex controller named LeadController that retrieves and updates Lead records.
Conclusion
By extending the Lightning Datatable and implementing a custom picklist editing solution, we overcome the limitations of inline editing for picklist fields in Salesforce Lightning. This customization significantly enhances the usability and functionality of Lightning components, providing a more seamless user experience.
If you'd like to see the code and resources used in this project, you can access the repository on GitHub.To access the AVENOIRBLOGS repository, click here. Feel free to explore the code and use it as a reference for your own projects.
Happy Coding! You can leave a comment to help me understand how the blog helped you. If you need further assistance, please contact us. You can click "Reach Us" on the website and share the issue with me.
Blog Credit:
P. Ahuja
Salesforce Developer
Avenoir Technologies Pvt. Ltd.
Reach us: team@avenoir.ai
Are you in need of Salesforce Developers?