In Salesforce, any Admin is able to restrict Picklist values based on RecordTypes. This enables a differentiation between business processes in data input and user guidance. Think of Case (Close) Reasons, or Opportunity Stages, showing different values dependent on whether it is a Question vs. Complaint Case, or a Sales vs. Service Opportunity. With this, the user is guided through the process and not distracted by Picklist values you don’t want to be available.
While the dependency between RecordType and Picklist values is respected in many UI locations in Salesforce, it is unfortunately not respected in Lightning Flow Choices. Causing all picklist values to be shown and losing the User Guidance.
This has been shared by many over the past years (Salesforce Idea – 633 votes) and many blog and StackOverflow posts discuss different options. Unfortunately, the response of Salesforce is limited to a Managed Package for dependent picklist values and the expectation is this will not be fixed before 2021 (while dependent picklists were added to Flow by Winter ’16)…
The solution
Luckily, there is a solution thanks to one of the latest Lightning Web Component feature: lightning-record-edit-form
. This beauty allows to make sure the picklist values only show the ones satisfying the database-validations and thus also RecordType dependencies (preventing exceptions like: INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST
).
Putting together, this feature and the usage of textual schema references, allows to create a generic easy-to-use component for any future RecordType Restricted Picklist Values in your Lightning Flow.
The final component is available at: git.foxy-solutions.com/LWC-RecordtType-PicklistValue-Selector.
What is it?
![RecordType Restricted Picklist Value Selector](https://www.foxy-solutions.com/wp-content/uploads/RecordTypePicklistValueSelector_FlowConfig.png)
This Lightning Web Component is a light-weight form containing one field. Based on the provided configuration, specifying Object and Field Name, the RecordTypeId and ability to enforce input – including custom error message – the component is loaded, showing only the values of the Picklist Field related to that RecordTypeId.
How to apply
In the LWC-RecordtType-PicklistValue-Selector repository, you can find the source code of this Lightning Web Component. Simply download the three LWC related files and deploy that to your own Salesforce environment.
Deploy to own environment: No developer on your project, or challenged is creating this new Lightning Web Component? Feel free to reach out, I’m more than happy to support you, or apply to make this an Unmanged package.
After deploying to your own Salesforce org, you can open any Lightning Flow Screen and drag-and-drop the component ‘RecordType Picklist Values’ to the screen. Specify the input to your context and you are good to go!
Implementation Considerations
- The input values in the screenshot above, are purely for documentation purposes to show the correct format;
- NEVER put a hard-coded RecordType Id as input. Either retrieve this dynamically from the record you want to edit/create (e.g.
{!sObj_Case.RecordTypeId}
) or query this via a GET-action (e.g.{!Get_RecType_CaseQuestion}
); - Best-practice is to display text using CustomLabels, especially when in multi-language context. The error message is therefore recommended to reference a Formula Resource (e.g.
{!Form_Label_RequiredPicklistValue}
), which fetches a CustomLabel ($Label.Flow_Validation_PicklistValueRequired
).
What’s behind it?
Aside from the usage of standard components there are a couple tricks which might be interesting to describe a bit more in details. For those interested, some documentation is provided for each of the three component files:
<template> <lightning-record-edit-form object-api-name={objectName} record-type-id={recordTypeId} > <lightning-input-field field-name={fieldName} value={fieldValue} required={isRequired} onchange={handleFieldChange} ></lightning-input-field> </lightning-record-edit-form> </template>
The template file (.html
) only contains a lightning-record-edit-form
which has two String parameters: object-api-name
and record-type-id
. While most documentation show the injection of Schema references, Salesforce also accepts textual-inputs, which is awesome, as this allows our component to be fully reusable and generic for any valid String combination of Object name and RecordTypeId.
// (..) Imports export default class RecordType_PicklistValues extends LightningElement { // (..) Attribute definitions /* Optional Attributes */ // {Boolean} Whether or not the input is required @api isRequired; // {String} Error message non selected @api errorMessage; /* Output Attributes */ // {String} API value of selected picklist value (not the label, but the value) @api fieldValue; // {Validation} Function Lightning Flows execute on 'next'-button to validate whether component is valid @api validate() { if( !this.isRequired || ( this.isRequired && this.fieldValue && this.fieldValue.length > 0 ) ){ return { isValid: true }; } else { return { isValid: false, errorMessage: this.errorMessage }; } } /** * Function to handle picklist selection and assign to fieldValue */ handleFieldChange( event ){ this.fieldValue = event.target.value; } }
In the Controller (.js
) only one thing is worth mentioning, as the rest only concerns standard Javascript logic: the @api
annotated validate()
function. This function is called by a Flow before moving to the next step, so on ‘next-button-click’. Flow will always call the validate() function on any component on the page, allowing custom validations, like making it conditionally required as is done in this particular component.
<?xml version="1.0" encoding="UTF-8"?> <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata"> <apiVersion>48.0</apiVersion> <description>RecordType Picklist Values</description> <isExposed>true</isExposed> <targets> <target>lightning__FlowScreen</target> <target>lightning__RecordPage</target> </targets> <targetConfigs> <targetConfig targets="lightning__RecordPage" > <property name="objectName" type="String" label="Object Name" required="true" /> <property name="recordTypeId" type="String" label="RecordTypeId" required="true" /> <property name="fieldName" type="String" label="Field to show picklist values for" required="true" /> </targetConfig> <targetConfig targets="lightning__FlowScreen" > <property name="objectName" type="String" label="1) Object API Name" role="inputOnly" /> <property name="fieldName" type="String" label="2) Picklist Field API Name" role="inputOnly" /> <property name="recordTypeId" type="String" label="3) RecordTypeId" role="inputOnly" description="Id of RecordType Id, fetch from record {!sObj_Account.RecordTypeId} or from Get {!Get_RecordType.Id}" /> <property name="isRequired" type="Boolean" label="4) Required input" role="inputOnly" default="false" /> <property name="errorMessage" type="String" label="5) Error message" role="inputOnly" description="Error message shown to customer when input required, but not populated" default="Please select a picklist value"/> <property name="fieldValue" type="String" label="Selected value by user" description="The API value of the selected Picklist value" /> </targetConfig> </targetConfigs> <masterLabel>RecordType Picklist Values</masterLabel> </LightningComponentBundle>
The metadata file can be fully understood when reading Salesforce documentation, but most important is to conclude:
- The component is exposed to both FlowScreens and RecordPages;
- Only on FlowScreens it is possible to add the
isRequired
attribute, since no validation is called on RecordPage; - Logically, one can deduct there is no reason of adding this component to a RecordPage (yet), since there will be no action triggered by selection, but this was more added for the showcase;
- Note, in the Flow Builder attributes are shown in alphabetical order. Hence, the
1), 2)
were prefixed to ensure the Admin is guided in the process of configuring this component. Role
is only defined for FlowScreens and can be set toInputOnly
andOutputOnly
. Attributes which can be used both for input and output, likefieldValue
, don’t need a role to be specified. Those are then available to both (default value).
Other options
Of course, there are still other options which could help you out, but in my perspective this requires more custom coding, or uncontrollable code in your environment.
- Create generic component which does a UI-API callout and show the retrieved values;
- Create Utility method using validFor() and Base64decode to find Picklist Dependencies (kinda like this);
- Install Managed Package which supports the same.
Conclusion
Finally, there is a work-a-round till Salesforce will make sure Dynamic Choices in Lightning Flows will be restricted by the available RecordType.
Feel free to apply this Lightning Web Component where needed. In case you have any feedback, improvements or suggestions, feel free to reach out so others can benefit from it as well.
Update 17-01-2022 – Unmanaged Package
After version requests this Lightning Web Component has been made available as Unmanaged Package to allow easier deployment to any Salesforce environment, aside from retrieving from the GIT repository and deploying yourself.
36 thoughts to “RecordType restricted picklist values in Flow”
Hi,
Thanks for the component.
It works well when I use it for Account object and Industry picklist field but it doesn’t work when I use it for Task object and Type picklist field. (It doesn’t work for any picklist field of Task object)
Are there any restrictions on which object we can use these LWC with ?
If yes, are there any workaround for those fields ?
Note : I have verified that all the API names and record type ID is are correct.
Thanks in Advance!
Hi Harsh, unfortunate to hear you’re having challenges to get the Task picklist dropdowns. Have you verified whether the user has Field-Level Security on those fields? Since Task is a joined object with Event/Activities, I might expect that insufficient permission might have been granted. This could be checked by e.g. displaying the picklist value on an existing record to that user. I have seen this component working with the Task object, so do expect it might be a standard precondition by Salesforce to not be satisfied. Please let me know if this indeed could resolve the issue, so others can find the fix as well, or else let me know your findings so I can think along. Hope the above can fix your challenge!
Hi Reinier, very helpful component!
It’s working perfectly for internal users but, how to make it visible for external users who access screen flow from salesforce site(without login). Could you please respond as it’s urgent for me to fix Production issue.
I think, adding lightningCommunity__Page in LWC XML file will resolve the issue. Could you please check and do the needful.
Hi Sai, so if I understand correctly you’re having a Screen Flow which properly shows the details for internal users but Guest users don’t have access. Since this is a component using standard forms of Salesforce, my guess would be this has to do with insufficient object- or field-level security. Could you let me know whether the Guest User profile (available from Setup > Sites > Open Site > Public Access Settings) has access to the field you want this component to display to the guest users?
lightningCommunity_Page
is purely for where this page can be dragged/loaded, though adding this on the page doesn’t make sense as there wouldn’t be a save button or logic. The screen-flow is the thing you render this in, so that should be sufficient. Hope you are able to resolve this with security settings, or else please feel free to reach out.Hello! We have encountered an issue when using your app.
When the user selects a picklist value attached to the component and goes next, then comes back to that picklist later before the completion of the flow, and chooses –None–, the user is allowed to go to the next screen. This is even when Required input = True.
I am happy to demo how to replicate the error.
Hi Trat, sorry to hear you’ve ran into this issue. If I understand you correctly this implies that the ‘None’ selection isn’t registered in the component and the ‘selected value’ remains the original value as if before right? Could you double check this by making a next screen where you display the selected textual value? If my hypothesis is correct the value should remain the same.
As I’m using the standard lightning-input-field component from Salesforce I believe it might be that there is no handleFieldChange() thrown at the moment of none-selection, which is definitely a bug. Please let me know whether the value is indeed not cleared and therefore one can proceed without satisfying the required-condition, so we can further investigate and potentially log a case with Salesforce (as I just checked and there are no conditions in my components).
Hope we’ll be able to resolve this issue for you shortly.
Great article.
Hello,
I installed this in a sandbox and added the component to a screen in the flow. The first time I ran the flow it worked great, but now when I run or debug the flow I no longer see the field on the screen. Any ideas why that would happen?
@Amanda, that’s unfortunate to hear! Not 100% sure what happened, but my thoughts would be on: 1) does the running user have FLS (Field Level Security) on the dropdown shown via this component; 2) Is the Flow version containing the component active and not accidentally disabled or overwritten by a colleague? 3) When you debug the Flow, is the component (not the field) ‘visible’? So do you see the passed parameters? Hope any of these might be the cause so it can be resolved, else let me know.
it is working awesome for picklist but for multiselect it is not working. Please guide how will it for work for multiselect restricted picklist.
This error occurred when the flow tried to create records: INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST: bad value for restricted picklist field
Hi @smriti, Thanks for your response! Please do also have a look at the previous comments from others. I think this might have to do with the same thing, where the default value is shown in the dropdown, but the lightning-input component out of the box, doesn’t assign the value. Hence, simply opening the dropdown and then selecting it manually should do the trick. Unfortunately, this behaviour is already known at Salesforce for a long time, but there has been no solution provided for it yet.
thanks alot using that to Allow filter of picklist values based on record type.
Hi Van,
Thank you for this component, your work is so great, I have used this component in a screen flow and the flow is used in Community page, when debugging the flow as a unauthenticated Guest User, this component gets displayed however when the same flow is accessed through the community page, the component doesn’t get displayed with right Record types for the object. I have provisioned all the access of the object(s) record type. Is there any setting in the code or the component that should be provisioned to be accessible by the Guest User on the Community page. please reply back.
Warm regards
Sid
Hi Sid! I’d believe the only option why the component doesn’t seem to load is that the Community User might not have Create/Edit permissions on that SObject, or no Edit rights on the field/picklist you want to show/populate? Depending on how technical you’re it might be worth to check in the page-source-code (using Developer Console elements inspector) whether the component is fully hidden, or whether the component is loading, but the record-form OR the input-field are hidden. That might help with the debugging. The beauty of this component lays in the simplicity and with that the lack of Apex code and the need for permissions (normally…). I hope it lays within Object or FLS permissions, else please let me know, maybe I can have a look within your Community. Thanks!
Hi Reinier,
What is the best way to reach you out.
Hello, It seems to work perfect in my org for a single picklist, is there something I can do to make it work for a dependent picklist?
Hi Danielle, great to hear it works fine for you and that’s for sure a relevant question. Given this LWC only uses out-of-the-box Salesforce code (lightning-record-edit-form and lightning-input-field) it depends on that. Fortunately, as you can see in documentation for lightning-input-field, this is definitely possible. To enable you’ll have to make a copy of this LWC and duplicate the lightning-input-field-attribute (and the variables referenced). This way the fields are related to eachother within the same form and you can provide both field details from Flow input. Do let me know if you run into issues, then I can see when I can make such component for you.
Please do note the remark posted in documentation: “When using a record type with a dependent picklist, we don’t recommend adding a default value that applies only to a specific controlling value. If you use a record type that has a default value set for the dependent picklist, this value is displayed in the picklist even though the controlling field might exclude the value.”
Hi there, i have installed the package into my org and configured the LWC as per instructions, my issue is that the LWC doesnt appear on the lightning flow page at all. I have other LWC that are rending correctly, just wondering what i have missed with this.
Hi Robert, that is unfortunate to hear! It can take some time for the ‘caching’ mechanism in Salesforce to recognize the LightningWebComponent and then the FlowBuilder to be updated. For sure it is needed to close the FlowBuilder if you were already working on it and re-open it after installation email confirmation. However, based on this thought, it would mean that you should for sure be able to see the component within your Flow now. Please let me know if that’s indeed the case, then I can add a note for future users, else I’m curious and happy to have a look to understand what is causing the not appearance. One last thought, was the component installed for the user profile used to modify the Flow? Curious for your response 🙂
Hello,
I have Install this Package to use in my one of the flow, Picklist value is displaying as expected, there is no problem, Issue I am facing is I marked this component as True, but still it is navigating to next screen if user didn’t select the value from the picklist.
Kindly help on this as soon as possible.
Thanks & Regards,
Saddam Hussain
Hi Saddam, unfortunate to hear the Required logic doesn’t seem to work. Can you maybe share a screenshot of the Flow configs and how it looks in the UI? Two things I can think of is that either no
errorMessage
is set, or the defaultfieldValue
is at least a space and not an empty string. Else I’ll have to investigate whether the required-Flow behaviour on thevalidate()
function is changed. Looking forward to your response!Since this is a screenflow, use a decision element to route back to the same screen.
I tried best practice for getting Record Type ID but it doesn’t work. How can it find that when the record hasn’t been created yet? Please let me know what I’m missing. Thank you.
Hi LW, the RecordType Id should be able to be fetched when querying the ‘RecordType’ object (see documentation). You can add a ‘Get Record’ element querying that Object specifying the
SObjectType
andDeveloperName
the RecordType is related to, which should give you the Id which can then be set on the SObject record you’re initiating and passed into this component. In case the RecordType query returns null, it might be worth to check the profile of the running user whether it has permission to see that RecordType (specified in the Object manager of the related SObject). In case this doesn’t work out, please let me know. Good luck!P.S. I’ve removed your comment regarding not seeing the component as I assume given your later comment the component showed up in Flow after waiting some time right?
Hi
I appreciated your component but when i have one value on a picklist marked as Default , it’s not working. The flow doesn’t populate my field.
DO you have an idea?
Thanks
Hi Claire, awesome to hear the component could help you partially for your request. I believe the default value will not be available by the lightning-input-field implementation of Salesforce. However, you might be able to ‘trick’ this around a bit. In your Flow you’ll assign the ‘fieldValue’ variable to derive the selected value of that picklist. When you would assign a Default value to that fieldValue variable resource in your flow, that should be selected on screen-load. This would still not allow you to show the configured Default, but might help you the initial bit.
One more thought, though that is kinda a wild guess… maybe you can initiate a record of the Object you want to show the picklist for and pass that reference into the Flow, I would expect Salesforce to populate the Default value when you create a Flow Variable Resource of type Object, and that would potentially allow to have it prefilled on the first screen load.
Hope that might help you out!
Thanks for developing this!
Please can I request that you release this component as an unmanaged package, so it can be quickly installed in a Salesforce org?
I do not know how to deploy a component such as this manually.
Thanks ?
Hi Gary, thanks for your reply and I’m happy to hear this might be of any help for you. Unfortunately, I’m away from my laptop for next week, so unable to reply to the fullest and see whether or not to release as unmanaged package.
Till that time you might be able to implement this in your sandbox (and production) via below link. Simply click the login button in the top right, connect and deploy. I haven’t been able to test this, but hope it can help you out in the meantime. Else I’ll come back to it in 1-2 weeks. Kind regards, Reinier
https://githubsfdeploy.herokuapp.com/?owner=FOXY+Solutions&repo=https://github.com/foxysolutions/LWC-RecordtType-PicklistValue-Selector/&ref=master
Tried using the herokuapp link but it just says it encountered an error.
Any chance this will be packaged in the future?
Hello same error, impossible for me to deploy
@Djelloul & @TomFord & @Gary, based on your requests I’ve just released an Unmanaged package to allow deploying this to any Salesforce server without the need of external tooling or Developer knowledge to handle SFDX CLI or IDEs.
For Production & Developer Orgs you can use: https://login.salesforce.com/packaging/installPackage.apexp?p0=04t08000000xAJR
For Sandboxes, use the above but replace login.salesforce.com by test.salesforce.com;
In case of any questions/challenges, please let me know!
This is super Reinier, I initially though of using UI API callout but this does seem to be a more cleaner approach .!
Hi Reinier van den Assum
I am trying to access the selected picklist value but it is showing null . any reason ?
Hi @Narendra! Apologies for the later reply. Do you mean in the LWC or in the Flow? It might be that Salesforce changed the implementation of the lightning-input-field onchange behaviour and you need to change the event.target.value to event.details; Might be worth to dump the event to see where the value sits. Feel free to send me an email with some more details, in case this is still impeding you. Happy development!
Hi Reinier, love the component!
I am having the same issue as noted above.
I have a screen flow with 2 screens, 1 where you pick the record type for Case, the other where the Type field is then restricted.
All is well and good, I pick LOA for example as record type, I am then given 2 options of Letter of Authority (default), and Letter of Appointment.
However if I was creating a case for Letter of Authority, and therefore didnt change the value of the Type field, the value stored when I go to create a Case as my next action is “null”.
If I click to change the value in Type to Letter of Appointment for example, and then back to Letter of Authority, the value is stored correctly.
Is this to do with the lightning-input-field onchange behaviour as you mentioned?
Or is there someway to store the default value if it isnt changed, as this is a common use case of a user not actually wanting to change the type from the default, and therefore it will create as null.
Thanks so much!
Hi Oliver, apologies for the later reply and unfortunate to hear the component is lacking on onload selections. What I’m curious for is whether this also happens when you make the selection required. In that way, the fieldValue remains undefined and the element should show a required message. This at least informs the end-user to make a selection. Here I’d expect the end-user to even be able to simply open the dropdown and select the already highlighted value, as this should trigger the assignment. The difficulty in this challenge, is that the ‘prefill’ of the default value is functionality within the standard lightning-input-field component of Salesforce and therefore it is very difficult to place a hook on it. I’ve already experimented some ways but couldn’t get it working unfortunately. You might raise a case, or post it online, though I’m honestly surprised to not be able to find a post on this already… Please do let me know your final approach/solution and how the required part worked out for you.