locked
Dropdown List Dependancy RRS feed

  • Question

  • I have created a dropdown list with multiple choices.  How do I limit these choices based upon the selected item in a previous dropdown list?

    For instance, List 1 contains 3 choices. List 2 contains 11 choices.  If item "A" is chosen in List 1, I only want List 2 to show 5 of 11 items in the dropdown list.
    Thursday, June 11, 2009 3:39 AM

Answers

  •  

    New Dependent Picklist Sample

     

    People frequently need to use client scripts to create dependent drop-down (picklist) fields. You can find many different approaches to do this in the CRM Forums and blog posts.

    We have had a “Dynamic Picklist” sample in the SDK for some time, but I received feedback that it didn’t work so well. The effort to fix that sample evolved into creating an entirely new sample. You can find the sample in the latest version of the Downloadable Microsoft CRM SDK. Look for it under \sdk\client\fullsample\dependentpicklist. The old “Dynamic Picklist” sample has been retired.

    In addition to fixing the problems with the existing sample, this new “Dependent Picklist” sample provides more features and illustrates a best practice for defining functions within form event code.

    Features

    Supports defining more than two dependent picklists. This allows you to chain together a number of picklist fields to increasingly more specific set of options.

    image

    Option mappings are defined in a separate section. Once you define how each field and each option is mapped to a parent option, you don’t need to make any changes to the code that does the filtering of options. These options are mapped using an array of objects defined using literal notation. This style of defining objects in an array is intended to make the mapping easier to read and edit.

       1: /* Map the dependencies START*/
       2:  /*
       3:  This sample maps 2 dependent picklists for this form. 
       4:    * new_category > new_subcategory
       5:    * new_subcategory > new_type
       6:  */
       7:  var gArrDependentPicklists =
       8:   [{
       9:  "ParentFieldId": "new_category",
      10:  "ChildFieldId": "new_subcategory",
      11:    "ChildFieldLabel": "Sub-Category",
      12:    "OptionsGroup":
      13:     [
      14:      {"ParentValue": "1",
      15:       "ChildOptionValues": ["", "1", "2", "3"]
      16:      },
      17:      {"ParentValue": "2",
      18:       "ChildOptionValues": ["", "4", "5", "6", "7", "8"]
      19:      }
      20:     ]
      21:    },
      22:    {
      23:    "ParentFieldId": "new_subcategory",
      24:    "ChildFieldId": "new_type",
      25:    "ChildFieldLabel": "Type",
      26:    "OptionsGroup":
      27:     [
      28:      {"ParentValue": "1",
      29:       "ChildOptionValues": ["", "1", "2", "3", "4"]
      30:      },
      31:      { "ParentValue": "2",
      32:        "ChildOptionValues": ["", "5", "6", "7"]
      33:      },
      34:      {"ParentValue": "3",
      35:       "ChildOptionValues": ["", "8", "9", "10", "11"]
      36:      },
      37:      {"ParentValue": "4",
      38:       "ChildOptionValues": ["", "12", "13", "14", "15"]
      39:      },
      40:      {"ParentValue": "5",
      41:       "ChildOptionValues": ["", "16", "17", "18", "19"]
      42:      },
      43:      {"ParentValue": "6",
      44:       "ChildOptionValues": ["", "20", "21", "22", "23"]
      45:      },
      46:      {"ParentValue": "7",
      47:       "ChildOptionValues": ["", "24", "25", "26", "27"]
      48:      },
      49:      {"ParentValue": "8",
      50:       "ChildOptionValues": ["", "28", "29", "30"]
      51:      }
      52:     ]
      53:    }
      54:   ];
      55: /* Map the dependencies END*/

    Provides a warning when the script is not synchronized with the options. Any script that creates dependent picklist options can be broken when new options are added. It would be very easy for someone to add a new options and not immediately notice that the script is affected. This script compares the number of options against the number of options that are mapped. If the number is different, an alert message will provide details alerting the customizer that the script is out of sync with the current options.

    image

    More resilient. Many of the dependent picklist samples you may find when searching the internet can rely on sets of contiguous options or may actually depend on the text labels provided for each option. This can cause the script to break if someone sorts the way the options are presented or if you are using a localized user interface. This sample shows how to avoid those problems.

    Defining reusable objects within the Onload event of a form

    When you look at the client side JScript samples provided before now in the CRM SDK you may notice that none of the samples include the definition of an object (or a function – a type of object) that might be re-used in another event, such as OnChange or OnSave. Although this is a common (some would say essential) practice it poses some problems for upgradability. Which object in the DOM should you attach your objects or functions to? Many people attach them to the CrmForm object. What happens if you define a function to CrmForm that has the same name as one of the functions provided by Microsoft CRM? There is a risk that the CRM function will be overwritten, potentially breaking some CRM functionality. What if CRM introduces a new function with the same name as one you have defined? Same result.

    This sample introduces the best practice of attaching objects to the window object through an arbitrary ‘namespace’ object. This should minimize the risk of overwriting objects in the DOM.

    For example, this sample requires that code in an Onchange event can access the filterChildField function defined in the OnLoad event. To make this available it is attached to a crmSDKSample object which is then attached the window object.

    //Create an arbitrary object to serve as a namespace
    var crmSDKSample = new Object();
    /*Attach the global dependancy array to the crmSdkSample object */
    crmSDKSample.gArrDependentPicklists = gArrDependentPicklists;
    /*Attach the function to the crmSDKSample*/
    crmSDKSample.filterChildField = filterChildFieldFunction;
    /*Attach the crmSDKSample to the window so it is globally available*/
    window.crmSDKSample = crmSDKSample;

    To call the function from the onChange event, the syntax looks like this:

    crmSDKSample.filterChildField("new_category", "new_subcategory");

    Because the window object is one part of the DOM that is almost certain to exist in future versions of CRM forms – this object is more likely to continue to be available after an upgrade.

    Sample Code

    As always, the sample code provided in the SDK are not intended to be used in a production environment without prior testing. You should deploy this sample to a test environment and examine it for interaction or interference with other parts of the system.

    I hope this sample provides you with some insights into creating dependent picklists as well as ideas about defining reusable objects within client script.

    Cheers


    Tiaan van Niekerk http://crmdelacreme.blogspot.com Skype:tiaan.van.niekerk1
    Thursday, June 11, 2009 5:01 AM

All replies

  • Microsoft provides a tool called the "Microsoft Dynamics CRM Demonstration Tools (for Microsoft Dynamics CRM 4.0)". This utility contains a Dependent Picklist creation utility. It can be located at http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=634508dc-1762-40d6-b745-b3bde05d7012 
    Thursday, June 11, 2009 4:08 AM
  • The latest SDK has recently updated code for a dynamic picklist. i'd give that a look-over.


    Leon Tribe
    Want to hear me talk about all things CRM? Check out my blog

    Want to hear me talk about all things CRM? Check out my blog http://leontribe.blogspot.com/
    • Proposed as answer by Leon TribeMVP Thursday, June 11, 2009 4:10 AM
    Thursday, June 11, 2009 4:10 AM
  • Hi John,

    This is the solution I propose.

    - Create both your picklists. (Lets assume 1 is category and 2 is sub-category)
    - Add all options to both your picklists. (again assume 1 has 3 options and 2 has 11).
    - Now add code to the OnChange event of the category picklist that removes values from the sub-category picklist based on the selection in the category picklist.

    Your code will look something like below.

     switch(crmForm.all.YourCategoryPicklist.SelectedText == 'Option1') 
     { 
            case 'Option1': 
                            crmForm.all.YourSubCategoryPicklist.DeleteOption(4);
                            crmForm.all.YourSubCategoryPicklist.DeleteOption(3); 
                            break; 
            case 'Option2': 
                             crmForm.all.YourSubCategoryPicklist.DeleteOption(2);
                             crmForm.all.YourSubCategoryPicklist.DeleteOption(1);
                            break; 
    }   

    Note: I have not tested this code. There might be typos. 

    Lastly. I do not recommend dynamically adding values from the sub-category picklist because you will have problem displaying stored values.


    Feel free to post back if you have more questions about the above.

    Hassan.


    Hassan Hussain | http://hassanhussain.wordpress.com/
    • Proposed as answer by Hassan Hussain Thursday, June 11, 2009 4:13 AM
    Thursday, June 11, 2009 4:13 AM
  •  

    New Dependent Picklist Sample

     

    People frequently need to use client scripts to create dependent drop-down (picklist) fields. You can find many different approaches to do this in the CRM Forums and blog posts.

    We have had a “Dynamic Picklist” sample in the SDK for some time, but I received feedback that it didn’t work so well. The effort to fix that sample evolved into creating an entirely new sample. You can find the sample in the latest version of the Downloadable Microsoft CRM SDK. Look for it under \sdk\client\fullsample\dependentpicklist. The old “Dynamic Picklist” sample has been retired.

    In addition to fixing the problems with the existing sample, this new “Dependent Picklist” sample provides more features and illustrates a best practice for defining functions within form event code.

    Features

    Supports defining more than two dependent picklists. This allows you to chain together a number of picklist fields to increasingly more specific set of options.

    image

    Option mappings are defined in a separate section. Once you define how each field and each option is mapped to a parent option, you don’t need to make any changes to the code that does the filtering of options. These options are mapped using an array of objects defined using literal notation. This style of defining objects in an array is intended to make the mapping easier to read and edit.

       1: /* Map the dependencies START*/
       2:  /*
       3:  This sample maps 2 dependent picklists for this form. 
       4:    * new_category > new_subcategory
       5:    * new_subcategory > new_type
       6:  */
       7:  var gArrDependentPicklists =
       8:   [{
       9:  "ParentFieldId": "new_category",
      10:  "ChildFieldId": "new_subcategory",
      11:    "ChildFieldLabel": "Sub-Category",
      12:    "OptionsGroup":
      13:     [
      14:      {"ParentValue": "1",
      15:       "ChildOptionValues": ["", "1", "2", "3"]
      16:      },
      17:      {"ParentValue": "2",
      18:       "ChildOptionValues": ["", "4", "5", "6", "7", "8"]
      19:      }
      20:     ]
      21:    },
      22:    {
      23:    "ParentFieldId": "new_subcategory",
      24:    "ChildFieldId": "new_type",
      25:    "ChildFieldLabel": "Type",
      26:    "OptionsGroup":
      27:     [
      28:      {"ParentValue": "1",
      29:       "ChildOptionValues": ["", "1", "2", "3", "4"]
      30:      },
      31:      { "ParentValue": "2",
      32:        "ChildOptionValues": ["", "5", "6", "7"]
      33:      },
      34:      {"ParentValue": "3",
      35:       "ChildOptionValues": ["", "8", "9", "10", "11"]
      36:      },
      37:      {"ParentValue": "4",
      38:       "ChildOptionValues": ["", "12", "13", "14", "15"]
      39:      },
      40:      {"ParentValue": "5",
      41:       "ChildOptionValues": ["", "16", "17", "18", "19"]
      42:      },
      43:      {"ParentValue": "6",
      44:       "ChildOptionValues": ["", "20", "21", "22", "23"]
      45:      },
      46:      {"ParentValue": "7",
      47:       "ChildOptionValues": ["", "24", "25", "26", "27"]
      48:      },
      49:      {"ParentValue": "8",
      50:       "ChildOptionValues": ["", "28", "29", "30"]
      51:      }
      52:     ]
      53:    }
      54:   ];
      55: /* Map the dependencies END*/

    Provides a warning when the script is not synchronized with the options. Any script that creates dependent picklist options can be broken when new options are added. It would be very easy for someone to add a new options and not immediately notice that the script is affected. This script compares the number of options against the number of options that are mapped. If the number is different, an alert message will provide details alerting the customizer that the script is out of sync with the current options.

    image

    More resilient. Many of the dependent picklist samples you may find when searching the internet can rely on sets of contiguous options or may actually depend on the text labels provided for each option. This can cause the script to break if someone sorts the way the options are presented or if you are using a localized user interface. This sample shows how to avoid those problems.

    Defining reusable objects within the Onload event of a form

    When you look at the client side JScript samples provided before now in the CRM SDK you may notice that none of the samples include the definition of an object (or a function – a type of object) that might be re-used in another event, such as OnChange or OnSave. Although this is a common (some would say essential) practice it poses some problems for upgradability. Which object in the DOM should you attach your objects or functions to? Many people attach them to the CrmForm object. What happens if you define a function to CrmForm that has the same name as one of the functions provided by Microsoft CRM? There is a risk that the CRM function will be overwritten, potentially breaking some CRM functionality. What if CRM introduces a new function with the same name as one you have defined? Same result.

    This sample introduces the best practice of attaching objects to the window object through an arbitrary ‘namespace’ object. This should minimize the risk of overwriting objects in the DOM.

    For example, this sample requires that code in an Onchange event can access the filterChildField function defined in the OnLoad event. To make this available it is attached to a crmSDKSample object which is then attached the window object.

    //Create an arbitrary object to serve as a namespace
    var crmSDKSample = new Object();
    /*Attach the global dependancy array to the crmSdkSample object */
    crmSDKSample.gArrDependentPicklists = gArrDependentPicklists;
    /*Attach the function to the crmSDKSample*/
    crmSDKSample.filterChildField = filterChildFieldFunction;
    /*Attach the crmSDKSample to the window so it is globally available*/
    window.crmSDKSample = crmSDKSample;

    To call the function from the onChange event, the syntax looks like this:

    crmSDKSample.filterChildField("new_category", "new_subcategory");

    Because the window object is one part of the DOM that is almost certain to exist in future versions of CRM forms – this object is more likely to continue to be available after an upgrade.

    Sample Code

    As always, the sample code provided in the SDK are not intended to be used in a production environment without prior testing. You should deploy this sample to a test environment and examine it for interaction or interference with other parts of the system.

    I hope this sample provides you with some insights into creating dependent picklists as well as ideas about defining reusable objects within client script.

    Cheers


    Tiaan van Niekerk http://crmdelacreme.blogspot.com Skype:tiaan.van.niekerk1
    Thursday, June 11, 2009 5:01 AM