0

In Visualforce/Standard Salesforce UI, if you have a required dependent picklist with only one value, it will default the field to that value and not allow the user to change the value.

Is there any way to replicate that functionality with lightning:input field? I know that we can get the picklist values in the apex controller but I'm hoping there's some way to get the filtered list based on the controlling field.

1
+50

Refer to the sample code extract below from the documentation.

The lightning:inputField of the dependent required picklist field gets defaulted if a single value exist.

This example uses LeadSource as the controlling field and Level__c as the dependent field for a dependent picklist.

<lightning:recordEditForm aura:id="recordViewForm"
                                  recordId="{!v.recordId}"
                                  objectApiName="Contact">
    <lightning:messages />
    <!--Other fields here-->
    <lightning:inputField fieldName="LeadSource" />
    <lightning:inputField fieldName="Level__c" />
    <lightning:button aura:id="submit" type="submit" label="Update record" class="slds-m-top_medium"/>
</lightning:recordEditForm>
  • That's not how I'm observing it working in my component – brezotom Oct 18 '19 at 14:10
  • check the API version of the component, it has to be API 42.0 or later – Shamina Oct 18 '19 at 14:12
0
public without sharing class DemoClass {
private static final String base64Chars = '' +
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
            'abcdefghijklmnopqrstuvwxyz' +
            '0123456789+/';
    public class Bitset{
        public Map<String,Integer> AlphaNumCharCodes {get;set;}
        public Map<String, Integer> Base64CharCodes { get; set; }

        public Bitset(){
          loadCharCodes();
        }

        //Method loads the char codes
        @TestVisible 
        public void loadCharCodes(){
            AlphaNumCharCodes = Constants.AlphaNumCharCodes;
            Base64CharCodes = new Map<String, Integer>();
            //lower case
            Set<String> pUpperCase = AlphaNumCharCodes.keySet();
            for(String pKey : pUpperCase) {
                //the difference between upper case and lower case is 32
                AlphaNumCharCodes.put(pKey.toLowerCase(),AlphaNumCharCodes.get(pKey)+32);
                //Base 64 alpha starts from 0 (The ascii charcodes started from 65)
                Base64CharCodes.put(pKey,AlphaNumCharCodes.get(pKey) - 65);
                Base64CharCodes.put(pKey.toLowerCase(),AlphaNumCharCodes.get(pKey) - (65) + 26);
            }

            //numerics
            for (Integer i=0; i<=9; i++){
                AlphaNumCharCodes.put(string.valueOf(i),i+48);
                //base 64 numeric starts from 52
                Base64CharCodes.put(string.valueOf(i), i + 52);
            }
        }
    }

    public class TPicklistEntry{
        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 TPicklistEntry(){

        }
        public TPicklistEntry(string label,string value){
            this.label=label;
            this.value=value;
        }
    }

    //----------------------------------------------------------------------------------------------------------
    //get dependent picklist values
    //
    //
    //----------------------------------------------------------------------------------------------------------
    public static Map<String,List<String>> getDependentOptions(String pObjName, String pControllingFieldName, String pDependentFieldName){

        Map<String,List<String>> objResults = new Map<String,List<String>>();
        //get the string to sobject global map
        Map<String,Schema.SObjectType> objGlobalMap = Schema.getGlobalDescribe();
        if (!objGlobalMap.containsKey(pObjName))
            return objResults;
        //get the type being dealt with
        Schema.SObjectType pType = objGlobalMap.get(pObjName);

        Map<String, Schema.SObjectField> objFieldMap = pType.getDescribe().fields.getMap();
        system.debug('objFieldMap' + objFieldMap);
        //verify field names
        if (!objFieldMap.containsKey(pControllingFieldName) || !objFieldMap.containsKey(pDependentFieldName))
            return objResults;
        //get the control values
        List<Schema.PicklistEntry> ctrl_ple = objFieldMap.get(pControllingFieldName).getDescribe().getPicklistValues();
        //get the dependent values
        List<Schema.PicklistEntry> dep_ple = objFieldMap.get(pDependentFieldName).getDescribe().getPicklistValues();
        //iterate through the values and get the ones valid for the controlling field name
        DemoClass.Bitset objBitSet = new DemoClass.Bitset();
        //set up the results
        for(Integer pControllingIndex=0; pControllingIndex<ctrl_ple.size(); pControllingIndex++){
            //get the pointer to the entry
            Schema.PicklistEntry ctrl_entry = ctrl_ple[pControllingIndex];
            //get the label
            String pControllingLabel = ctrl_entry.getLabel();
            //create the entry with the label

            objResults.put(pControllingLabel,new List<String>());
        }
        //Added Navin - For None value
        if(!objResults.containsKey('--None--')){
            objResults.put('--None--',new List<String>{'--None--'});
        }
        //End
        //check the dependent values
        for(Integer pDependentIndex=0; pDependentIndex<dep_ple.size(); pDependentIndex++){
            //get the pointer to the dependent index
            Schema.PicklistEntry dep_entry = dep_ple[pDependentIndex];
            //get the valid for
            String pEntryStructure = JSON.serialize(dep_entry);

            DemoClass.TPicklistEntry objDepPLE = (DemoClass.TPicklistEntry)JSON.deserialize(pEntryStructure, DemoClass.TPicklistEntry.class);
            //if valid for is empty, skip
            if (objDepPLE.validFor==null || objDepPLE.validFor==''){
                continue;
            }
            String validForBits = base64ToBits(objDepPLE.validFor);
            //iterate through the controlling values
            for (Integer i = 0; i < validForBits.length(); i++) {
                // For each bit, in order: if it's a 1, add this label to the dependent list for the corresponding controlling value
                String bit = validForBits.mid(i, 1);
                if (bit == '1') {
                       String pControllingLabel = ctrl_ple[i].getLabel();
                    objResults.get(pControllingLabel).add(objDepPLE.label);
                }
            }
        }
        if(objResults!=null){
            for(String pControllingLabel  :objResults.keyset()){
                //Added Navin - To remove duplicate None value
                if(pControllingLabel != '--None--'){ //End
                    objResults.get(pControllingLabel).add(new TPicklistEntry('--None--','--None--').label);
                }

            }
        }
        return objResults;
    }
    // Convert decimal to binary representation (alas, Apex has no native method :-(
    //    eg. 4 => '100', 19 => '10011', etc.
    // Method: Divide by 2 repeatedly until 0. At each step note the remainder (0 or 1).
    // These, in reverse order, are the binary.
    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;
    }

    // Convert a base64 token into a binary/bits representation
    // e.g. 'gAAA' => '100000000000000000000'
    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;
    }
}

in this class Call the method getDependentOptions and pass the parameters.

to get the picklist values you can simply using Schema object. You can use below code to get picklist values: public static Map sObjectFieldInfoMap; List pick_list_values = sObjectFieldInfoMap.get(field_name).getDescribe().getPickListValues();

  • That... is a ton of code and a server call for something that really should just work out of the box... – brezotom Oct 18 '19 at 13:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.