Filter Picklist Values Based on Record Type

  • Retrieving a picklist value based on record type is possible in VF page using standard controller
  • In lightning, Salesforce UI API supports a functionality to filter a picklist value based on record type based on this idea
  • You can download the code from Here

 

Use Case: 

I have picklist values based on Record Type defined as below:

Now, If we want to get this metadata in lightning and want to display dropdowns based on Record Type of any given record.

We might be thinking of using any Schema class. But unfortunately, we don’t have schema class supported for this use case.  We wanted output like this for the record which has record type mentioned in the previous screenshot.

So, Let’s take a look at the solution.

Below is the approach to leverage Salesforce UI API to retrieve picklist value based on record type:

  • Create a connected app
  • Create an Auth Provider
  • Create Named Credentials
  • Create lightning component
  • Create Apex class to call UI API

 

  1. Create a connected app:
  • setup > create apps > create new app
  • Provide any URL as a callback URL for now. We will replace it with new URL in later steps when we will create Auth Provider
  • For Oauth scope provide “Full access (full)” & ”Perform requests on your behalf at any time (refresh_token, offline_access)”

connected_app

 

  1. Create an Auth Provider
  • Create Auth Provider from Setup > Security Control > create a new Auth. provider
  • Set provider type as “Salesforce”
  • Provide consumer key & consumer secret from apps that is created in step 1
  • Set the default scope as a “full refresh_token offline_access”
  • Click save

auth_provider

  • Cope the Callback URL from “Salesforce Configuration” section and paste it to Callback URL in app that you have created in step 1.

 

  1. Create Named Credentials
  • Setup > Named Credentials > Create new named credentials
  • Set the URL as a base URL of your org
  • Set Identity type as a “Named Principal”
  • Set authentication protocol as a “Oauth 2.0”
  • Select Authentication Provider as a Auth. Provider that you created in step 2.
  • Provide the scope as a “full refresh_token offline_access”
  • Select “Start Authentication Flow on Save”
  • Click Save > It will ask for credentials to authenticate, provide that

named_credentials

 

  1. Create a lightning component
<aura:component implements="lightning:availableForFlowScreens,force:appHostable,flexipage:availableForAllPageTypes,forceCommunity:availableForAllPageTypes" 
               access="public" controller="PicklistBasedOnRecordTypeController">
   
   <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
   
   <!-- input attribute  -->
   <aura:attribute name="objectAPIName" type="String" access="public" description="API name of object" />
   <aura:attribute name="fieldAPIName" type="String" access="public" description="API name of field" />
   <aura:attribute name="fieldLabel" type="String" access="public" description="Label of field" />
   <aura:attribute name="recordTypeDeveloperName" type="String" access="public" description="Developer name of Record Type of object" />
   <aura:attribute name="required" type="Boolean" default="false" access="public" description="Picklist is required or not" />
   
   <!-- output attribute  -->
   <aura:attribute name="selectedValue" type="String" access="public" description="Selected picklist value" />
   
   <aura:attribute name="pickListOptions" type="object[]" access="public" description="List of picklist values" />
   
   <lightning:select aura:id="picklist" name="pickListValues" label="{!v.fieldLabel}" required="{!v.required}" value="{!v.selectedValue}">
   	<aura:iteration var="option" items="{! v.pickListOptions }">
           <option value="{!option.value}">{!option.label}</option>
       </aura:iteration>
   </lightning:select>
   
</aura:component>
  • Javascript controller.js code
({
    doInit : function(component, event, helper) {
        helper.getPicklistValuesBasednRecordType(component);
    },
})
  • Javascript helper.js code
({
    getPicklistValuesBasednRecordType : function(component) {
        
        var objectAPIName = component.get("v.objectAPIName");
        var fieldAPIName = component.get("v.fieldAPIName");
        var recordTypeDeveloperName = component.get("v.recordTypeDeveloperName");
        
        var action = component.get("c.getPicklistValueBasedonRecordType");
        
        action.setParams({
            objectAPIName : objectAPIName,
            fieldAPIName : fieldAPIName,
            recordTypeDeveloperName : recordTypeDeveloperName
        });
        
        action.setCallback(this, function(response){
            this.handleResponse(response, component);
        });
        
        $A.enqueueAction(action);
        
	},
    
    handleResponse : function(response, component){
        if (response.getState() === "SUCCESS") {
            if (!$A.util.isEmpty(response.getReturnValue())) {
                var picklistOptions = [];
                var noneValue = {};
                noneValue["value"] = "";
                noneValue["label"] = "--None--";
                picklistOptions.push(noneValue);
                var returnedValues = JSON.parse(response.getReturnValue());
                if (!$A.util.isEmpty(returnedValues)) {
                    returnedValues.forEach(function(returnedValue){
                        var picklistValue = {};
                        picklistValue["value"] = returnedValue.value;
                        picklistValue["label"] = returnedValue.label;
                        picklistOptions.push(picklistValue);
                    });
                    component.set("v.pickListOptions", picklistOptions);
                }
            }else{
                console.log("Couldn't find an picklist values.");
            }
        } else if (response.getState() === "ERROR") {
            var errors = res.getError();
            if (errors) {
                if (errors[0] && errors[0].message) {
                    console.log(errors[0].message);
                }
            }
        } else{
            console.log("Unknow error!");
        }
    },
})

 

  1. Create an apex controller
/**
* @Author		:		Rajat Koradiya
* @Date		:		20-Sept-2018
* @Desc		:		Controller for picklist based on record type lightning component
* */
public with sharing class PicklistBasedOnRecordTypeController {
   
   @AuraEnabled 
   public static String getPicklistValueBasedonRecordType(String objectAPIName, String fieldAPIName, String recordTypeDeveloperName){
       
       list<PicklistValue> picklistValues = new list<PicklistValue>();
       
       //get record type Id
       list<RecordType> recordTypes = [Select Id, Name From RecordType  Where SobjectType = :objectAPIName and DeveloperName = :recordTypeDeveloperName limit 1];
       Id recordTypeId = (!recordTypes.isEmpty()) ? recordTypes.get(0).Id : null;
       
       if(recordTypeId != null){
           
           String method = 'GET';
           String endpoint = String.format('/services/data/v43.0/ui-api/object-info/{0}/picklist-values/{1}/{2}', new String[]{ objectAPIName, recordTypeId, fieldAPIName });
           
           HttpRequest request = new HttpRequest();
           request.setEndpoint('callout:UI_API_Named_Credentials'+endPoint);
           request.setMethod(method);
           
           HTTPResponse response = (new Http()).send(request);
           
           if(response.getStatusCode() == 200){
               
               Map<String,Object> root = (Map<String,Object>) JSON.deserializeUntyped(response.getBody());
               if(root.containsKey('values')){ 
                   List<Object> picklistVals = (List<Object>)root.get('values');
                   for(Object picklistVal : picklistVals){
                       Map<String,Object> picklistValMap = (Map<String,Object>) picklistVal;
                       picklistValue pickVal = new picklistValue();
                       pickVal.value = (String) picklistValMap.get('value');
                       pickVal.label = (String) picklistValMap.get('label');
                       picklistValues.add(pickVal);
                   }
               }
               
           }
           
       }
       
       return JSON.serialize(picklistValues);
   }
   
   public class PicklistValue{
       public String value {get;set;}
       public String label {get;set;}
   }
}

 

One thought on “Filter Picklist Values Based on Record Type in Lightning”

Comments are closed.