+ Start a Discussion
Anupama@28Anupama@28 

How to get sObject's dependent picklist in lightning component

Hi, 

How to get sObject's dependent picklist in lightning component.
I have tried through <force:inputfield> but no luck.

Thanks,
Anupama


 
Anupama@28Anupama@28
Hi,

Our requirement is to display the community user's contact details, where user should be able to view or update their own contact.
The other fields are displaying and updating fine but i m not able to display the country and state fields and their values.
I have tried with the following,

1: Using <ui:inputText> I am able to dispaly the current values of country and state but we want to display it along with other drodown values as well so that user can change and update
2: <force:inputField> didnt work
3: inputSelect is just displaying empty picklist 

Thanks,
Anupama
 
sfdcMonkey.comsfdcMonkey.com
you can fetch country and state picklist values and set it to ui:inputselect component 
i write a post on it 
http://www.sfdcmonkey.com/2016/12/05/how-to-fetch-picklist-value-from-sobject-and-set-in-uiinputselect/ 
let me infrom if it helps you 
thanks 
Anupama@28Anupama@28
Hi Piyush,

It fetches all the country and all the state values, but our requirement is it should properly work like controlling and dependent picklist for example if I select 'INDIA' as country then state field should display only states values of INDIA.

Thanks,
Anupama
 
sfdcMonkey.comsfdcMonkey.com
hi Anupama
ok, i will create a sample post on it. and pingback you ASAP
thanks 
renuka mudgalrenuka mudgal
Hi Piyush,

I also need the same functionality. Waiting for your post.

Thanks.
Anupama@28Anupama@28
Hi ,

I have tried with the code given in the below link , but here the problem is it is not fetching the proper states for few countries .
http://titancronus.com/blog/2014/05/01/salesforce-acquiring-dependent-picklists-in-apex/

Thanks,
Anupama
sfdcMonkey.comsfdcMonkey.com
Here is the code for dependent pick list fields in lightning component
http://www.sfdcmonkey.com/2017/02/18/dependent-picklist-fields-lightning-component/
Hopes it's helps you
thanks
dandamudidandamudi
@piyush_soni,

i used u r http://www.sfdcmonkey.com/2016/12/05/how-to-fetch-picklist-value-from-sobject-and-set-in-uiinputselect/  
to bind the picklist values from sobject columns. 
but my task slight different like
i have multiple picklist like 10 , i want bind the values for them from sobject like first get sobject then i have used where condition based field i passed from Dropdown then i have to use on columns values to that pick list.

Thanks in Advance



 
sai tharunsai tharun
I have the same requiremnt but the country fields has to be multiple picklist value & based on that the respective BU has to come. Can any one help me in this task. Like If I Select India & US the states of India & Us has to get populated. 
Arjun Ghosh 9Arjun Ghosh 9
Yes, its a known issue.You may vote for this idea if you feel

Method/alternate way to easily access dependent picklist fields in Lightning Component
https://success.salesforce.com/ideaView?id=0873A000000LnhyQAC
Glyn Anderson (Slalom)Glyn Anderson (Slalom)
There is a new, concise implementation of the dependent picklist problem here: https://glyntalkssalesforce.blogspot.com/2018/08/dependent-picklist-values-in-apex.html.  It uses a single method with about 30 lines of Apex code; and the post include test code as well.   Hope it helps!
Pramod ke 21Pramod ke 21
Hi ,

I have implemted the logic. But my depended pick list are not updating/ displaying  properly. Can you please fix the issue. My code as follows:

public class ContactListController {
        
    @AuraEnabled
    public static List<Contact> getContactList(list<Id> accountIds) {
        // Getting the list of contacts from where Id is in accountIds
                List<Contact> contactList = [SELECT Id, FirstName,LastName, Email, Phone, AccountId,Country__c,City__c FROM Contact WHERE accountId In:accountIds];
                system.debug('Conta=='+contactList);        
        // Returning the contact list
        return contactList;
    }
    
    @AuraEnabled
    public static Map<string, string> saveContacts(list<contact> contactList){
        system.debug('inside'+contactList);
        Map<string, string> resultMap = new Map<string,string>();
        try{
            
            update contactList;
            system.debug('contactList'+contactList);
            resultMap.put('status', 'success');
            resultMap.put('messgae', 'contacts updated successfully');
        }catch(exception e){
            resultMap.put('status', 'error');
            resultMap.put('messgae', e.getMessage());
        }
        return resultMap;
    }
    
       
    @AuraEnabled 
    public static Map<String, List<String>> getDependentMap(string contrfieldApiName,string depfieldApiName) {
        system.debug('==='+contrfieldApiName+'=='+depfieldApiName);
        String controllingField = contrfieldApiName.toLowerCase();
        String dependentField = depfieldApiName.toLowerCase();
        
        Map<String,List<String>> objResults = new Map<String,List<String>>();
        
        Schema.sObjectType objType = Contact.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(){            
        }
        
    }

}


 
Pramod ke 21Pramod ke 21
===============================================================================================
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" controller="ContactListController" access="global" >
    <!--to get dependent picklist values-->
    <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="controllingFieldAPI" type="string" default="Country__c" description="store field API name of Controller field"/>
    <aura:attribute name="dependingFieldAPI" type="string" default="City__c" description="store field API name of dependent field"/>
    <aura:attribute name="bDisabledDependentFld" type="boolean" default="true"/> 
    <aura:attribute name="objDetail" type="contact" default="{'sobjectType' : 'contact'}"/>
    
    <!-- Handler to call function when page is loaded initially -->
    <aura:handler name="init" action="{!c.getContactsList}" value="{!this}" />
    <aura:attribute name="contact" type="Contact"
                    default="{
                             'SObjectType': 'Contact',
                             'FirstName': '',
                             'LastName': '',
                             'Email': '',
                             'Phone': '',
                             'Country__c': '-none-',
                             'City__c': '-none-'
                             }"/>
    <!-- List of contacts stored in attribute -->
    <aura:attribute name="contactList" type="List" />
    <lightning:card title="Contacts">
            <p class="slds-p-horizontal_small">
        <div aura:id="recordViewForm">
            <aura:iteration items="{!v.contactList}" var="contact">
                <lightning:recordViewForm recordId="{!contact.Id}" objectApiName="Contact">
                    <div class="slds-box slds-theme_default"> 
                        <lightning:input type="checkbox" label="selete contact to delete" value="{!contact.Id}" aura:id="deletecontactid"/>
                        <lightning:outputField fieldName="FirstName" />
                        <lightning:outputField fieldName="LastName" />
                        <lightning:outputField fieldName="Email"/>
                        <lightning:outputField fieldName="Phone"/>
                        <lightning:outputField fieldName="Country__c"/>
                        <lightning:outputField fieldName="City__c"/>
                    </div>   
                </lightning:recordViewForm>
                <br/>
            </aura:iteration>
        </div>
        
        <div aura:id="recordEditForm" class="formHide">
            <aura:iteration items="{!v.contactList}" var="contact">
                <div class="slds-box slds-theme_default">
                    <lightning:input value="{!contact.FirstName}" />
                    <lightning:input value="{!contact.LastName}" />
                    <lightning:input value="{!contact.Email}" type="email" />
                    <lightning:input value="{!contact.Phone}" type="tel" pattern="\([0-9]{3}\) [0-9]{3}-[0-9]{4}" />
                     <lightning:select name="controllerFld"
                          value="{!contact.Country__c}"
                          label="Country"
                          onchange="{!c.onControllerFieldChange}">
            <aura:iteration items="{!v.listControllingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
                    <lightning:select name="dependentFld"
                          value="{!contact.City__c}"
                          label="City"
                          disabled="{!v.bDisabledDependentFld}">
            <aura:iteration items="{!v.listDependingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
                    
                    
                </div>
            </aura:iteration>
        </div>
        </p>   
        
          <aura:set attribute="actions">
            <!-- New button added -->
            <lightning:button label="New Contact" name="contactModal" onclick="{!c.openModal}" />
            <lightning:button label="New" onclick="{!c.newContact}" />
            <lightning:button label="edit" variant="brand" name="edit" onclick="{!c.editContacts}"/>
            <lightning:button label="Delete" variant="destructive" onclick="{!c.deleteContacts}"/>
        </aura:set>
    </lightning:card>
    <div >
        <section aura:id="contactModal" role="dialog" tabindex="-1" aria-labelledby="contactModalHeading" aria-modal="true" aria-describedby="contactModalBody" class="slds-modal">
            <div class="slds-modal__container">
                <header class="slds-modal__header">
                    <lightning:buttonIcon class="slds-modal__close" alternativeText="Close" title="Close" iconName="utility:close" onclick="{!c.closeModal}" variant="bare-inverse" size="large"></lightning:buttonIcon>
                    <h2 id="contactModalHeading" class="slds-text-heading_medium slds-hyphenate">New Contact</h2>
                </header>
                <div class="slds-modal__content slds-p-around_medium" id="contactModalBody">
                    <lightning:input label="FirstName"/>
                    <lightning:input label="Lastname"/>
                    <lightning:input label="Email"/>
                    <lightning:input label="Phone"/>
                </div>
                <footer class="slds-modal__footer">
                    <lightning:button onclick="{!c.closeModal}" variant="neutral">Cancel</lightning:button>
                    <lightning:button onClick="{!c.createContact}" variant="brand">Save</lightning:button>>
                </footer>
            </div>
        </section>
        <div aura:id="contactModalBackdrop" class="slds-backdrop"></div>
    </div>
</aura:component>
================================================================================================
({
    getContactsList : function(component, event, helper) {
        helper.fetchcontacts(component, event, helper);
         
    },
    // Function used to create a new Contact
    newContact: function(component, event, helper) {
        // Global event force:createRecord is used
        var createContact = $A.get("e.force:createRecord");
        // Parameters like apiName and defaultValues are set
        createContact.setParams({
            "entityApiName": "Contact",
            "defaultFieldValues": {
                "AccountId": component.get("v.recordId")
            }
        });
        // Event fired and new contact dialog open
        createContact.fire();
    },
    editContacts: function(component, event, helper){
        //alert('press');
        var btn= event.getSource();
        var name= btn.get('v.name');
        var recordViewForm = component.find('recordViewForm');
        var recordEditForm = component.find('recordEditForm');
        var controllingFieldAPI = component.get("v.controllingFieldAPI");
        var dependingFieldAPI = component.get("v.dependingFieldAPI");
        helper.fetchPicklistValues(component,controllingFieldAPI, dependingFieldAPI);
        if(name=='edit'){
            $A.util.addClass(recordViewForm,'formHide');
            $A.util.removeClass(recordEditForm,'formHide');
            btn.set('v.name','save');
            btn.set('v.label','save');
        }else{
            helper.saveContacts(component,event,helper);
            // get the fields API name and pass it to helper function  
            
            //var objDetails = component.get("v.contact");
            //alert(objDetails);
            // call the helper function
            
       
            
        }
        
    },
    
    
    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);
        }
    },
    
    
})

================================================================================================
({
    fetchcontacts : function(component,event,helper) {
        //alert('test');
        var action = component.get("c.getContactList");
        //var action=component.get("c.getContactList");
        //alert(action);
        var accountid=component.get("v.recordId");
        action.setParams({
            accountIds: accountid
        });
        action.setCallback(this, function(response){
            var state=response.getState();
        if(state === 'SUCCESS'){
           // alert(state);
            var contactList = response.getReturnValue();
            //alert(contactList);
            component.set("v.contactList",contactList);
        }else{
            alert('Error in getting the data');
        }
        });
        $A.enqueueAction(action);
    },
    
    
    saveContacts: function(component,event,helper){
        var contactList = component.get("v.contactList");
        var recordViewForm = component.find('recordViewForm');
        var recordEditForm = component.find('recordEditForm');
        var toastEvent = $A.get('e.force:showToast');
        var saveAction = component.get("c.saveContacts");
        saveAction.setParams({ contactList: contactList});
        saveAction.setCallback(this, function(response) {
         var state = response.getState();  
             var btn=event.getSource();
            //alert(state);
        if(state==='SUCCESS'){
            alert(state);
            var dataMap = response.getReturnValue();
           // alert(dataMap.message);
            $A.util.removeClass(recordViewForm,'formHide');
            $A.util.addClass(recordEditForm,'formHide');
            var btn=event.getSource();
            btn.set('v.name','edit');
            btn.set('v.label','Edit');
            alert('test');
            toastEvent.setParams({
                        'title': 'Success!',
                        'type': 'success',
                        'mode': 'dismissable',
                        'message': dataMap.messgae
                    });
             toastEvent.fire();  
        }  else{
            alert('error');
        }        
                               
                               });
        $A.enqueueAction(saveAction);
},
    
    
    fetchPicklistValues: function(component,controllerField, dependentField) {
        // call the server side function 
        alert('inside'); 
        var action = component.get("c.getDependentMap");
        // pass paramerters [object definition , contrller field name ,dependent field name] -
        // to server side function 
        action.setParams({
            'contrfieldApiName': controllerField,
            'depfieldApiName': dependentField 
        });
        //set callback   
        action.setCallback(this, function(response) {
            alert(response.getState());
            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);
        
    },
})