Easy dependent picklists for Dynamics CRM

I've created a new solution for creating dependent picklists on Dynamics CRM forms that requires no coding to implement. You can download it from my Crm-Sample-Code GitHub repository here: https://raw.githubusercontent.com/lucasalexander/Crm-Sample-Code/master/misc-code-samples/easydependentpicklists.js

Assume you have three picklists with related options like in the list below:

  • lpa_level1picklist
    • 1
    • 2
  • lpa_level2picklist
    • 1a
    • 1b
    • 2a
    • 2b
  • lpa_level3picklist
    • 1a1
    • 1a2
    • 1b1
    • 2a1

You can represent a tree of possible options like this:
1 -> 1a -> 1a1
1 -> 1a -> 1a2
1 -> 1b -> 1b1
2 -> 2a -> 2a1
2 -> 2a -> 1a1
2 -> 2b

Should notice two important points:

  1. You don't have to have an equal number of options in each path. For example, under 2 -> 2b, there are no children. In this case the new_level3 picklist should show no options when 2 -> 2b is selected in the two parent picklists.
  2. The same child can appear in multiple option paths. That is, level 3's "1a1" is a child of both "1a" and "2a."

To implement this filtering functionality on a CRM form, you just need to add my JavaScript file to your solution as a web resource and then call its initializePicklistFilter function when you want to apply the filtering. This could be in the form onload event or at any other time it makes sense.

The initializePicklistFilter function takes three input parameters:

  1. picklists - A pipe-delimited string that contains the picklists in the hierarchy in order of first parent to last child.
    Example: "lpa_level1picklist|lpa_level2picklist|lpa_level3picklist"

  2. separator - String of characters used to separate levels in the parent-child option paths. This can be any string you like.
    Example: " -> "

  3. optionTree - An array of strings containing all possible parent-child option paths you want to enable on the form.
    Example: ["1 -> 1a -> 1a1","1 -> 1a -> 1a2","1 -> 1b -> 1b1","2 -> 2a -> 2a1","2 -> 2a -> 1a1","2 -> 2b"]

Putting it all together, your call to initializePicklistFilter for this example would look like this:

initializePicklistFilter(  
  "lpa_level1picklist|lpa_level2picklist|lpa_level3picklist",
  "->",
  ["1 -> 1a -> 1a1",
    "1 -> 1a -> 1a2",
    "1 -> 1b -> 1b1",
    "2 -> 2a -> 2a1",
    "2 -> 2a -> 1a1",
    "2 -> 2b"]
);

Here are a few points to consider:

  1. My code is based on the optionset labels, so it does not automatically support multiple languages. If you need to handle multiple languages, you would need to create a separate option tree array for each language and then call the initializePicklistFilter function with the corresponding array depending for the user's language.
  2. Because the initializePicklistFilter call can be executed any time you want (and even at multiple times for the same set of pickilists on a form), you can dynamically modify the options based on external criteria. For example, you could use this to create different possible selection rules based on user roles.
  3. My example uses a three-level picklist hierarchy, but this solution works for any number of picklists.
  4. To apply picklist filters for multiple groups of picklists on the same form, just call the initializePicklistFilter multiple times with different parameters.
  5. The chaining all possible paths through the option tree can make the initializePicklistFilter call unwieldy for picklists with lots of options. If your child options only depend on their immediate parents, you can chain together multiple initializePicklistFilter calls. That is, you can call it for the first parent and first child, then call it again for the first child and its first child, then that child and its child, etc.

That's all for now. If you use this solution or have any thoughts, I'd love to hear about it in the comments.

comments powered by Disqus