2

We are trying to implement field dependency in custom picklist field type with LWC. For this I created one LWC component to define custom lightning datatable. And I am using custom picklist fields which are dependent. Dependent fields are country and state. When changing country , automatically depended state need to load in custom picklist.

For this , From custom picklist onchange method, I am generating and sending one custom event to my main component by passing changed country value. But getting [NoErrorObjectAvailable] Script error with showing This page has an error. You might just need to refresh it. messsage while loading component,

Error Message

[NoErrorObjectAvailable] Script error. newErrorHandler()@https://static.lightning.force.com/ap24/auraFW/javascript/wyQWsVjjDIx-Xsqekbsbwg/aura_proddebug.js:67451:14 errorHandlerWrapper()@https://static.lightning.force.com/ap24/auraFW/javascript/wyQWsVjjDIx-Xsqekbsbwg/aura_proddebug.js:67467:25 dispatchEvent()@https://static.lightning.force.com/ap24/auraFW/javascript/wyQWsVjjDIx-Xsqekbsbwg/aura_proddebug.js:12804:25 LightningCombobox.dispatchEvent()@https://static.lightning.force.com/ap24/auraFW/javascript/wyQWsVjjDIx-Xsqekbsbwg/aura_proddebug.js:6928:18 LightningCombobox.value [as dispatchEvent]()@https://static.lightning.force.com/ap24/auraFW/javascript/wyQWsVjjDIx-Xsqekbsbwg/aura_proddebug.js:6172:48 LightningCombobox.handleSelect()@https://milletechdatasoftsystempvtl-

Error screen

enter image description here

My added .js code for sending controlling field format like the following,

     @wire(getObjectInfo, { objectApiName: myRegObject })
    objectInfo;

      @wire(getPicklistValues, 
        {recordTypeId: "$objectInfo.data.defaultRecordTypeId",fieldApiName: countryField})
    wireCountryPickList({ error, data }) 
        {
          if (data) {
              this.countryOptions = data.values;
          } 
          else if (error) {
              console.log(error);
          }
      }

      @wire(getPicklistValues, 
        {
          recordTypeId: "$objectInfo.data.defaultRecordTypeId",
          fieldApiName: stateField,
          controllingFieldValue: '$data.country__c'
        })
    wireStatePickList({ error, data }) 
        {
          if (data) {
              this.allStateOptions = data.values;
             
          } 
          else if (error) {
              console.log(error);
          }
      }

    @wire(getRegDetails, { pickList: '$countryOptions' })
    result(result){
      
      let sRObj = JSON.parse(JSON.stringify(result));
      this.sDetails = sRObj.data;    
        try
          {
            this.sDetails.forEach(ele => {
              ele.countryOptionsList = this.countryOptions;
              ele.stateOptionsList = this.allStateOptions;
              })
          }
        catch(err) {
            console.log(err.message);
        }
    } 


     handleControllingChange(event) {

         const selectedCountry = event.detail.value;
         console.log(selectedCountry);     
         this.stateOptions = this.allStateOptions
                            .filter(option => option.validFor.includes(selectedCountry));

         this.sDetails.forEach(ele => {
          ele.stateOptionsList = this.stateOptions;
          })
      
      }

And I am defining custom field in same .js file like the fllowing,

    const COLUMNS = [
    { 
      label : 'Country',
      fieldName: 'country__c',
      name : 'Country' ,
      placeholder : 'Choose Country',
      type: 'countryPicklist',
      typeAttributes: {
        value: { fieldName: 'country__c' },
        options: { fieldName: 'countryOptionsList' },
        },
      editable: true,
      context: { fieldName: 'Id' }
    },
    { 
      label : 'State',
      fieldName: 'state__c',
      name : 'State' ,
      placeholder : 'Choose State',
      type: 'statePicklist',
      typeAttributes: {
        value: { fieldName: 'state__c' },
        options: { fieldName: 'stateOptionsList' },
        },
      editable: true,
      context: { fieldName: 'Id' }
    },
    {
        type: 'button',
        typeAttributes: { label: 'Delete', name: 'delete' }
    }
    ]

And My custom picklist field created by extending LightningDatatable like the following,

    import LightningDatatable from 'lightning/datatable';

    import countryPicklist from './countryPicklist.html';
    import countryPicklistEdit from './countryPicklistEdit.html';
    import statePicklist from './statePicklist.html';
    import statePicklistEdit from './statePicklistEdit.html';


    export default class CustomDataTable extends LightningDatatable {

    static customTypes = {
        
         countryPicklist: {
            template: countryPicklistEdit,
            editTemplate: countryPicklist,
            standardCellLayout: true,
            typeAttributes: ['options', 'value']
        },
        statePicklist: {
            template: statePicklistEdit,
            editTemplate: statePicklist,
            standardCellLayout: true,
            typeAttributes: ['options', 'value']
        }
    };
    handleCountryChange(event) {
       
         const selectedCountry = event.detail.value;
    console.log(selectedCountry);
    this.dispatchEvent(new CustomEvent('countrychange', {detail: selectedCountry}));
    }
    }

Field Templates I am using for picklist custom type like the following, countryPicklistEdit.html,

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

countryPicklist.html,

      <template>
        <lightning-combobox 
        name='picklist' 
        label='Country'
        placeholder='Choose Country' 
        value={typeAttributes.value}
        options={typeAttributes.options}
        onchange={handleCountryChange}
        data-inputable="true"
        dropdown-alignment="auto"
        variant='label-hidden'>
       </lightning-combobox>
     </template>

And I am displaying data in my main html file like the following,

    <template>
      <c-custom-data-table
         key-field="Id" 
         data={sDetails} 
         show-row-number-column 
         onsave={handleSave}
         oncountrychange={handleControllingChange}
         hide-checkbox-column 
         columns={columns}
         onrowaction={handleRowAction}>
       </c-custom-data-table>
    </template>

Custom Object Definition already added field dependencies for Country to State fields. Problem here because of custom picklist.

Troubleshooted Way -

  1. At custom component .js file, to cross check whether event.detail has any problem or not by keeping one constant value to selectedCountry and passed by creating custom event. But not working.

  2. Cross checked the naming convention while creating and sending custom events from child to parent.

  1. Tested whether simple test messages using console.log statement. Even nothing printing. When changes country value to different value, immediately shows the error screen.

Problem I felt here with the onchange method defined for custom datatable , while changing country value to different value. Error page shows immediately after I changes country value. The html file is where I am defining onchange method is not my child component's html. Its additional html file added in the same directory and importing using import countryPicklist from './countryPicklist.html'; statement.

Updated Error in Console,

enter image description here

So can anyone suggest / guide to get a solution for this problem?

1 Answer 1

-1

can you try the below:

@wire(getPicklistValues, 
    {
      recordTypeId: "$objectInfo.data.defaultRecordTypeId",
      fieldApiName: minuteField
    })
wireMinutePickList({ error, data }) 
    {
      if (data) {
          this.minuteOptions = data.values;
//Getting the index of the controlling value as the single value can be dependant on multiple controller value
                let minuteOptionsControllerIndex = this.minuteOptions.controllerValues[this.hour__c];//assuming u have hour stored

let minuteOptionsTemp = [];
                this.minuteOptions.values.forEach((key) => {
                    for (let i = 0; i < key.validFor.length; i++) {
                        if (minuteOptionsControllerIndex === key.validFor[i]) {
                            minuteOptionsTemp.push({
                                label: key.label,
                                value: key.value
                            });
                        }
                    }
                });

this.minutesToDisplay = minuteOptionsTemp;
      } 
      else if (error) {
          console.log(error);
      }
  }

and the html can be as follows:

 <lightning-combobox name="Minute" label="Minute" class="validateField"
                                    options={minutesToDisplay}>
                                </lightning-combobox>
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your guidance. Yes let me try this way. But I have one confusion here. What I need to pass this.minuteOptions.controllerValues[this.hour__c] in the place of this.hour__c ?. Becasue my controlling data is hour. That is also one custom picklist field. And I am getting hours data from another wired method while loading component. And I am storing hours data in this.hoursOptionPicklist. So In this code what I need to define ? Do I need to use $data.hour__c or this.hoursOptionPicklist ?
If hour is a picklist, you can get your value on change of the picklist and store in a variable
I updated code to do the same functionality using country and state. And modified to give more idea about my code. Can you please check my updated code and please suggest how I need to manage the controlling filed there?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.