function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
fiona gentryfiona gentry 

Why Picklist Not Populating Data for Custom Dependent Picklist Field With lightning:select In Lightning Component

Hi Gurus,

I am trying to replicate the below functionality of Custom Dependent Picklist Field With lightning: select In Lightning Component for Custom Object (Ref:-Source (https://sfdcmonkey.com/2018/08/31/dependent-picklist-lightningselect-lightning-salesforce/)),

Only difference here is i am using Custom object `ERT_Case_Type_Data__c` and its 2 picklist `Level_1__c` and `Level_2__c` instead of standard object `Contact` reference in the article


Below are ERT_Case_Type_Data__c Object and data details
User-added imageUser-added image

Here is TestApp which uses this component, Unfortunately, I don't see data in the dropdown Picklist
Please help me in knowing what is wrong I am doing here


Here is Apex class dependentPicklist_UpdateCtrl.apxc
 
public class dependentPicklist_UpdateCtrl {
					@AuraEnabled 
					public static Map<String, List<String>> getDependentMap(sObject objDetail, string contrfieldApiName,string depfieldApiName) {
						String controllingField = contrfieldApiName.toLowerCase();
						String dependentField = depfieldApiName.toLowerCase();
						
						Map<String,List<String>> objResults = new Map<String,List<String>>();
						
						Schema.sObjectType objType = objDetail.getSObjectType();
						if (objType==null){
							return objResults;
						}
						
						Map<String, Schema.SObjectField> objFieldMap = objType.getDescribe().fields.getMap();
						
						if (!objFieldMap.containsKey(controllingField) || !objFieldMap.containsKey(dependentField)){
							return objResults;     
						}
						
						Schema.SObjectField theField = objFieldMap.get(dependentField);
						Schema.SObjectField ctrlField = objFieldMap.get(controllingField);
						
						List<Schema.PicklistEntry> contrEntries = ctrlField.getDescribe().getPicklistValues();
						List<PicklistEntryWrapper> depEntries = wrapPicklistEntries(theField.getDescribe().getPicklistValues());
						List<String> controllingValues = new List<String>();
						
						for (Schema.PicklistEntry ple : contrEntries) {
							String label = ple.getLabel();
							objResults.put(label, new List<String>());
							controllingValues.add(label);
						}
						
						for (PicklistEntryWrapper plew : depEntries) {
							String label = plew.label;
							String validForBits = base64ToBits(plew.validFor);
							for (Integer i = 0; i < validForBits.length(); i++) {
								String bit = validForBits.mid(i, 1);
								if (bit == '1') {
									objResults.get(controllingValues.get(i)).add(label);
								}
							}
						}
						return objResults;
					}
					
					public static String decimalToBinary(Integer val) {
						String bits = '';
						while (val > 0) {
							Integer remainder = Math.mod(val, 2);
							val = Integer.valueOf(Math.floor(val / 2));
							bits = String.valueOf(remainder) + bits;
						}
						return bits;
					}
					
					public static String base64ToBits(String validFor) {
						if (String.isEmpty(validFor)) return '';
						
						String validForBits = '';
						
						for (Integer i = 0; i < validFor.length(); i++) {
							String thisChar = validFor.mid(i, 1);
							Integer val = base64Chars.indexOf(thisChar);
							String bits = decimalToBinary(val).leftPad(6, '0');
							validForBits += bits;
						}
						
						return validForBits;
					}
					
					private static final String base64Chars = '' +
						'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
						'abcdefghijklmnopqrstuvwxyz' +
						'0123456789+/';
					
					
					private static List<PicklistEntryWrapper> wrapPicklistEntries(List<Schema.PicklistEntry> PLEs) {
						return (List<PicklistEntryWrapper>)
							JSON.deserialize(JSON.serialize(PLEs), List<PicklistEntryWrapper>.class);
					}
					
					public class PicklistEntryWrapper{
						public String active {get;set;}
						public String defaultValue {get;set;}
						public String label {get;set;}
						public String value {get;set;}
						public String validFor {get;set;}
						public PicklistEntryWrapper(){            
						}
						
					}
				}

Here is Component code dependentPicklist_UpdateCtrl.cmp
 
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction"
								access="global"
								controller="dependentPicklist_UpdateCtrl">
					<!-- call doInit function on component load -->  
					<aura:handler name="init" value="this" action="{!c.doInit}"/>
					
					<!-- aura attributes-->  
					<aura:attribute name="listControllingValues" type="list" default="[]" description="to store controller field values"/>
					<aura:attribute name="listDependingValues" type="list" default="['--- None ---']" description="to store dependent field values"/>
					<aura:attribute name="depnedentFieldMap" type="map" description="map to store dependent values with controlling value"/>
					<aura:attribute name="bDisabledDependentFld" type="boolean" default="true"/> 
					
					<aura:attribute name="objDetail" type="ERT_Case_Type_Data__c" default="{'sobjectType' : 'ERT_Case_Type_Data__c'}"/>
					<aura:attribute name="controllingFieldAPI" type="string" default="Level_1__c" description="store field API name of Controller field"/>
					<aura:attribute name="dependingFieldAPI" type="string" default="Level_2__c" description="store field API name of dependent field"/>
					
					<!--Controller Field-->
					<lightning:layoutItem size="12" padding="around-small">    
						<lightning:select name="controllerFld"
										  value="{!v.objDetail.Level_1__c}"
										  label="Level1"
										  onchange="{!c.onControllerFieldChange}">
							<aura:iteration items="{!v.listControllingValues}" var="val">
								<option value="{!val}">{!val}</option>
							</aura:iteration>
						</lightning:select>
					</lightning:layoutItem>
					
					<!--Dependent Field-->
					<lightning:layoutItem size="12" padding="around-small">
						<lightning:select name="dependentFld"
										  value="{!v.objDetail.Level_2__c}"
										  label="Level2"
										  >
							<aura:iteration items="{!v.listDependingValues}" var="val">
								<option value="{!val}">{!val}</option>
							</aura:iteration>
						</lightning:select>
					</lightning:layoutItem>
					
				</aura:component>


Here is Controller code for dependentPicklist_UpdateCtrlController.js
 
({
					doInit : function(component, event, helper) { 
						// get the fields API name and pass it to helper function  
						var controllingFieldAPI = component.get("v.controllingFieldAPI");
						var dependingFieldAPI = component.get("v.dependingFieldAPI");
						var objDetails = component.get("v.objDetail");
						// call the helper function
						helper.fetchPicklistValues(component,objDetails,controllingFieldAPI, dependingFieldAPI);
					},
					
					onControllerFieldChange: function(component, event, helper) {     
						var controllerValueKey = event.getSource().get("v.value"); // get selected controller field value
						var depnedentFieldMap = component.get("v.depnedentFieldMap");
						
						if (controllerValueKey != '--- None ---') {
							var ListOfDependentFields = depnedentFieldMap[controllerValueKey];
							
							if(ListOfDependentFields.length > 0){
								component.set("v.bDisabledDependentFld" , false);  
								helper.fetchDepValues(component, ListOfDependentFields);    
							}else{
								component.set("v.bDisabledDependentFld" , true); 
								component.set("v.listDependingValues", ['--- None ---']);
							}  
							
						} else {
							component.set("v.listDependingValues", ['--- None ---']);
							component.set("v.bDisabledDependentFld" , true);
						}
					},
				})

Here is Helper code for dependentPicklist_UpdateCtrlControllerHelper.js
 
({
					fetchPicklistValues: function(component,objDetails,controllerField, dependentField) {
						// call the server side function  
						var action = component.get("c.getDependentMap");
						// pass paramerters [object definition , contrller field name ,dependent field name] -
						// to server side function 
						action.setParams({
							'objDetail' : objDetails,
							'contrfieldApiName': controllerField,
							'depfieldApiName': dependentField 
						});
						//set callback   
						action.setCallback(this, function(response) {
							if (response.getState() == "SUCCESS") {
								//store the return response from server (map<string,List<string>>)  
								var StoreResponse = response.getReturnValue();
								
								// once set #StoreResponse to depnedentFieldMap attribute 
								component.set("v.depnedentFieldMap",StoreResponse);
								
								// create a empty array for store map keys(@@--->which is controller picklist values) 
								var listOfkeys = []; // for store all map keys (controller picklist values)
								var ControllerField = []; // for store controller picklist value to set on lightning:select. 
								
								// play a for loop on Return map 
								// and fill the all map key on listOfkeys variable.
								for (var singlekey in StoreResponse) {
									listOfkeys.push(singlekey);
								}
								
								//set the controller field value for lightning:select
								if (listOfkeys != undefined && listOfkeys.length > 0) {
									ControllerField.push('--- None ---');
								}
								
								for (var i = 0; i < listOfkeys.length; i++) {
									ControllerField.push(listOfkeys[i]);
								}  
								// set the ControllerField variable values to country(controller picklist field)
								component.set("v.listControllingValues", ControllerField);
							}else{
								alert('Something went wrong..');
							}
						});
						$A.enqueueAction(action);
					},
					
					fetchDepValues: function(component, ListOfDependentFields) {
						// create a empty array var for store dependent picklist values for controller field  
						var dependentFields = [];
						dependentFields.push('--- None ---');
						for (var i = 0; i < ListOfDependentFields.length; i++) {
							dependentFields.push(ListOfDependentFields[i]);
						}
						// set the dependentFields variable values to store(dependent picklist field) on lightning:select
						component.set("v.listDependingValues", dependentFields);
						
					},
					
				})

Please help me in identifying why data not displayed in Picklist dropdown only difference here is that its an Custom object with dependent Picklist

Regards,
​​​​​​​Fiona