Reputation: 2421
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
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 -
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.
Cross checked the naming convention while creating and sending custom events from child to parent.
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,
So can anyone suggest / guide to get a solution for this problem?
Upvotes: 2
Views: 1118
Reputation: 29
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>
Upvotes: -1