CRM 2011 Dependent Option Set Example


With the introduction of  Option Sets in CRM 2011 (formerly known as picklists), it is now possible to create common drop-down lists across multiple entities and forms. On a recent project I had a specific requirement to build a solution that used two related option sets. If I selected a particular country from the first drop-down, the region would automatically selected from the second drop-down.

That doesn’t sound too tricky, and indeed writing a small amount of JScript I was able to achieve this fairly quickly. The problem came about when I wanted to use these option sets multiple times on a single entity. In this example, I needed to track “Country of Birth”, “Country of Residence” and “Tax Residency” as well as the associated regions. Now I have three variations of the same JScript code, with the only difference being the CRM schema names of the various country and region fields.

This got me thinking. Could I build a JScript library that would allow me to reuse the dependent option set logic, without having to hard-code specific field names? A quick search through the CRM 2011 SDK revealed several major enhancements to the client-side programming model, and of specific interest to me were:

  1. The ability to access the form execution context. When you associate a JScript library function with a CRM form event (such as a field OnChange event), you can now pass the execution context as a parameter to your function. The execution context object has a method called getEventSource(), which returns a reference to the field that triggered the event. In this example, I no longer have to hard-code the name of the country field that triggered the OnChange event.
  2. The ability to pass additional parameters to a JScript library function. In this example I specify the name of the region field as an additional parameter, instead of using a hard-coded value in my code.

So what does my code look like? Below, I have a simple JScript function called attributeOnChange(), which takes the both execution context and the dependent attribute name as input parameters. After some some simple error handling, the function then calls a second function getDependentAttributeValue(), which actually does the work of selecting the correct region, based on which country was selected. I’ve chosen to use the names attribute and dependentAttribute instead of country and region, so I can reuse this code for any dependent option sets.

   1: function attributeOnChange(context, dependentAttributeName) {
   2:     // Check the context object exists and that it has a method getEventSource()
   3:     if ((context != "undefined") && (context != null) && (context.getEventSource)) {
   5:         // Get the attribute that triggered this event
   6:         var attribute = context.getEventSource();
   8:         // Check the attribute type is an OptionSet
   9:         if (attribute.getAttributeType() == "optionset") {
  11:             // Check the dependent attribute name has been passed as a parameter, and that it is a string
  12:             if ((dependentAttributeName != "undefined") && (dependentAttributeName != null) && (typeof (dependentAttributeName) == "string")) {
  14:                 // Get the dependent attribute object from the CRM page
  15:                 var dependentAttribute =;
  17:                 // Check the dependent attribute object exists
  18:                 if ((dependentAttribute != "undefined") && (dependentAttribute != null)) {
  20:                     // Check the dependent attribute type is an OptionSet
  21:                     if (dependentAttribute.getAttributeType() == "optionset") {
  23:                         // Get the selected attribute OptionSet value
  24:                         var attributeValue = attribute.getValue();
  26:                         // Lookup the dependent attribute OptionSet value
  27:                         var dependentAttributeValue = this.getDependentAttributeValue(attributeValue);
  29:                         // Update the dependent attribute OptionSet
  30:                         dependentAttribute.setValue(dependentAttributeValue);
  31:                     }
  32:                     else {
  33:                         alert("The second parameter of this function should be the name of an OptionSet attribute. The attribute \"" + dependentAttributeName + "\" is not an OptionSet.");
  34:                     }
  35:                 }
  36:                 else {
  37:                     alert("The second parameter of this function \"" + dependentAttributeName + "\" is not a valid attribute name.");
  38:                 }
  39:             }
  40:             else {
  41:                 alert("This function requires you to pass the name of the dependent attribute as the second parameter e.g. \"crm_attributename\".");
  42:             }
  43:         }
  44:         else {
  45:             alert("This function should only be used with an OptionSet attribute. The attribute \"" + attribute.getName() + "\" is not an OptionSet.");
  46:         }
  47:     }
  48:     else {
  49:         alert("This function requires you to pass the execution context as the first parameter.");
  50:     }
  51: }

So now I have the necessary option sets and JScript library to solve my original problem, all that’s left is to add the fields to a form, and wire-up the OnChange() event as shown.

CRM 2011 Dependent Option Set Example

As you can see, I have selected the “Pass execution context as first parameter” checkbox, and specified the name of the region field “srh_region”, not forgetting to put quotes around the name. If you want to try this out in your own CRM 2011 environment, I have exported my solution as an unmanaged package, which you may download here.

This posting is provided “AS IS” with no warranties, and confers no rights.

Laughing Boy Chestnuts Pre-School Chain Gang

Comments (4)

  1. Thorsten Klenke says:

    thanks for your good sample and in general the introduction to the new jscript objects.

    I´ve imported your solution to a RC and set the srh_region field to "read-only" on the form. In this case changes on the srh_region object will not be saved. To achieve this I added dependentAttribute.setSubmitMode("always") in line 25. Is that a good solution for you?

    Now I´ll have a look to your continuance

    Greeting from Germany


  2. Thorsten says:

    Good post. thanks

  3. Terri Harman says:

    Thanks for the example.  When I my script runs the and then tests if the object set to it is undefined or null, it returns null.  Can we refer to Xrm.Page info with "Pass execution context…" checked?  

  4. kiran says:

    thanks for the Example . It help me a lot 🙂