1

My component showing Controlling picklist and dependent picklist values as expected. But when i edit Controlling picklist then dependent picklist showing all values not related to the Controlling picklist. How i can show dependent picklist based on controlling picklist selected?

lWCDatatableWithPicklist.html

<template if:true={data}>
                <c-l-w-c-custom-datatable-type
                    key-field="Id"
                    data={data} 
                    columns={columns} 
                    onvalueselect={handleSelection}
                    draft-values={draftValues} 
                    oncellchange={handleCellChange}
                    onsave={handleSave}
                    oncancel={handleCancel}
                    hide-checkbox-column>
                </c-l-w-c-custom-datatable-type>
            </template>

lWCDatatableWithPicklist.js

import { LightningElement, track, wire } from 'lwc';
import fetchAccounts from '@salesforce/apex/CaseController.getCases';
import ACCOUNT_OBJECT from '@salesforce/schema/Project_Budgets__c';
import TYPE_FIELD from '@salesforce/schema/Project_Budgets__c.Spend_Category_T__c';
import TYPE_DFIELD from '@salesforce/schema/Project_Budgets__c.Spend_Sub_Category_T__c';
import { updateRecord } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { refreshApex } from '@salesforce/apex';
import { getPicklistValues, getObjectInfo } from 'lightning/uiObjectInfoApi';
 
const columns = [
    { label: 'Name', fieldName: 'Name', editable: true },
    {
        label: 'Spend_Category_T__c', fieldName: 'Spend_Category_T__c', type: 'picklistColumn', editable: true, typeAttributes: {
            placeholder: 'Choose Type', options: { fieldName: 'pickListOptions' }, 
            value: { fieldName: 'Spend_Category_T__c' }, // default value for picklist,
            context: { fieldName: 'Id' } // binding account Id with context variable to be returned back
        }
    },
    {
        label: 'Spend_Sub_Category_T__c', fieldName: 'Spend_Sub_Category_T__c', type: 'picklistDColumn', editable: true, typeAttributes: {
            placeholder: 'Choose Type', options: { fieldName: 'pickListDOptions' }, 
            value: { fieldName: 'Spend_Category_T__c' }, // default value for picklist,
            context: { fieldName: 'Id' } // binding account Id with context variable to be returned back
        }
    },

    { label: 'Line Item Description', fieldName: 'Line_Item_Description__c', type: 'text', editable: true },
    { label: 'Calculation Description', fieldName: 'Calculation_Description__c', type: 'text', editable: true },
    { label: 'NGO and ILP Discussion', fieldName: 'NGO_and_ILP_Discussion__c', type: 'text', editable: true },
    { label: 'Q1', fieldName: 'Q1__c', type: 'currency', editable: true },
    { label: 'Q2', fieldName: 'Q2__c', type: 'currency', editable: true },
    { label: 'Q3', fieldName: 'Q3__c', type: 'currency', editable: true },
    { label: 'Q4', fieldName: 'Q4__c', type: 'currency', editable: true },
    { label: 'First Half Budget', fieldName: 'First_Half_Amount__c', type: 'currency', editable: true },
    { label: 'Second Half Budget', fieldName: 'Second_Half_Amount__c', type: 'currency', editable: true },
    { label: 'Total Annual Budget', fieldName: 'Total_Annual_Budget__c', type: 'currency', editable: true },

]
 
export default class CustomDatatableDemo extends LightningElement {
    columns = columns;
    showSpinner = false;
    @track data = [];
    @track accountData;
    @track draftValues = [];
    lastSavedData = [];
    @track pickListOptions;
    @track pickListDOptions;
 
    @wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
    objectInfo;
 
    //fetch picklist options
    @wire(getPicklistValues, {
        recordTypeId: "$objectInfo.data.defaultRecordTypeId",
        fieldApiName: TYPE_FIELD
    })
 
    wirePickList({ error, data }) {
        if (data) {
            console.log('Picklist'+data)
            this.pickListOptions = data.values;
            console.log('pickListOptions',this.pickListOptions)
        } else if (error) {
            console.log(error);
        }
    }

    @wire(getPicklistValues, {
        recordTypeId: "$objectInfo.data.defaultRecordTypeId",
        fieldApiName: TYPE_DFIELD
    })
 
    wireDPickList({ error, data }) {
        if (data) {
            console.log('DPicklist',data.values);
            this.pickListDOptions = data.values;
            console.log('pickListOptions',this.pickListDOptions)
        } else if (error) {
            console.log(error);
        }
    }
 
    //here I pass picklist option so that this wire method call after above method
    @wire(fetchAccounts, { pickList: '$pickListOptions',pickDList:'pickListDOptions' })
    accountData(result) {
        this.accountData = result;
        if (result.data) {
            this.data = JSON.parse(JSON.stringify(result.data));
 
            this.data.forEach(ele => {
                ele.pickListOptions = this.pickListOptions;
                ele.pickListDOptions=this.pickListDOptions;
            })
 
            this.lastSavedData = JSON.parse(JSON.stringify(this.data));
 
        } else if (result.error) {
            this.data = undefined;
        }
    };
 
    updateDataValues(updateItem) {
        let copyData = JSON.parse(JSON.stringify(this.data));
 
        copyData.forEach(item => {
            if (item.Id === updateItem.Id) {
                for (let field in updateItem) {
                    item[field] = updateItem[field];
                }
            }
        });
 
        //write changes back to original data
        this.data = [...copyData];
    }
 
    updateDraftValues(updateItem) {
        let draftValueChanged = false;
        let copyDraftValues = [...this.draftValues];
        //store changed value to do operations
        //on save. This will enable inline editing &
        //show standard cancel & save button
        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];
        }
    }
 
    //handler to handle cell changes & update values in draft values
    handleCellChange(event) {
        //this.updateDraftValues(event.detail.draftValues[0]);
        let draftValues = event.detail.draftValues;
        draftValues.forEach(ele=>{
            this.updateDraftValues(ele);
        })
    }
 
    handleSave(event) {
        this.showSpinner = true;
        this.saveDraftValues = this.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.draftValues = [];
            return this.refresh();
        }).catch(error => {
            console.log(error);
            this.showToast('Error', 'An Error Occured!!', 'error', 'dismissable');
        }).finally(() => {
            this.draftValues = [];
            this.showSpinner = false;
        });
    }
 
    handleCancel(event) {
        //remove draftValues & revert data changes
        this.data = JSON.parse(JSON.stringify(this.lastSavedData));
        this.draftValues = [];
    }
 
    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.accountData);
    }
    
    handleAddRow() {
        // Create a new blank row with default values
        const newRow = {
            Id: '', // Generate a unique identifier if needed
            Name: '',
            Spend_Category_T__c: '', // Blank value for picklist
            Spend_Sub_Category_T__c: '', // Blank value for picklist
            Line_Item_Description__c: '',
            Calculation_Description__c: '',
            NGO_and_ILP_Discussion__c: '',
            Q1__c: '',
            Q2__c: '',
            Q3__c: '',
            Q4__c: '',
            First_Half_Amount__c: '',
            Second_Half_Amount__c: '',
            Total_Annual_Budget__c: '',
            pickListOptions: this.pickListOptions, // Assign picklist options
            pickListDOptions: this.pickListDOptions, // Assign picklist options
        };
    
        // Add the new row to the data array
        this.data = [...this.data, newRow];
    
        // Update draft values if needed
        this.draftValues = [...this.draftValues, newRow];
    }
}

lWCCustomdatatable.html

<template>

</template>

lWCCustomdatatable.js

import LightningDatatable from 'lightning/datatable';
import picklistColumn from './picklistColumn.html';
import pickliststatic from './pickliststatic.html';
import picklistDColumn from './picklistDColumn.html';
import picklistDstatic from './picklistDstatic.html'; 
export default class LWCCustomDatatableType extends LightningDatatable {
    static customTypes = {
        picklistColumn: {
            template: pickliststatic,
            editTemplate: picklistColumn,
            standardCellLayout: true,
            typeAttributes: ['label', 'placeholder', 'options', 'value', 'context', 'variant','name']
        },
        picklistDColumn: {
            template: picklistDstatic,
            editTemplate: picklistDColumn,
            standardCellLayout: true,
            typeAttributes: ['label', 'placeholder', 'options', 'value', 'context', 'variant','name']
        }
        
    };
    
}

picklistColumn.html

<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>

picklistDColumn.html

<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

<template>
    <span class="slds-truncate" title={value}>{value}</span>
</template>

picklistDstatic.html

<template>
    <span class="slds-truncate" title={value}>{value}</span>
</template>

1 Answer 1

1

Your code, displays all values even after editing the controlling picklist. You have to Update the Dependent Picklist Options Dynamically.

In lWCDatatableWithPicklist.js, modify the handleCellChange function to update the dependent picklist options based on the selected controlling picklist value:

    handleCellChange(event) {
    let draftValues = event.detail.draftValues; 
    draftValues.forEach((ele) => {
      this.updateDraftValues(ele);

      // Find the row being updated
      const updatedRow = this.data.find((row) => row.Id === ele.Id);

      // Update dependent picklist options based on controlling picklist
      if (ele.hasOwnProperty('Spend_Category_T__c')) {
        const selectedCategory = ele.Spend_Category_T__c;

      // Filter dependent picklist options based on the selected category
      const filteredDOptions = this.pickListDOptions.filter((option) => {
        // Implement your logic here to filter based on the category 
        return option.value === selectedCategory; // Replace with your filter condition
       });

       updatedRow.pickListDOptions = filteredDOptions;
      }
    });
   this.data = [...this.data]; // Update the data array with updated row
   }

Explanation:

  • The code iterates through the changed rows in the draftValues array.
  • It finds the corresponding row in the data array based on the Id field.
  • If the edited field is Spend_Category_T__c, it filters the pickListDOptions array based on your chosen filtering logic (replace the example condition with your specific criteria).
  • The filtered options are then assigned to the pickListDOptions property of the updated row.
  • Finally, the entire data array is updated with the modified row.
2
  • Hi @Jashuva P, Great Thanks a lot man, This is what im looking for. Commented Mar 5 at 9:31
  • Hi @jashuva-p, Thanks for your solutions it working as expecting for existing records. but add new row showing all dependent picklist. when select picklist then its throwing an error This page has an error. You might just need to refresh it. First, would you give us some details? (We're reporting this as error ID: 1662493193) . Is it possible add new row and save new records and existing records using custom lightning data table? Commented Mar 7 at 6:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .