Cascading of Two Multi-Select Option Set fields in Dynamics 365 v9.0

By | April 1, 2019

Introduction

Microsoft introduced Multi Select Option Set in Dynamics 365 V9.0, which will help us to select more than one option.

Recently we had a business requirement, where the client required multi-select option set values to populate programmatically on selection of another multi-select option set.

To achieve this, first, we need to create two multi-select option set fields in CRM e.g. Mobile Company (Parent Multi-Select option set) and Mobile Handset (Child Multi-Select option set).

Then we need to create one JSON web resource in Dynamics 365 CRM, where we can define child option set values against each parent option set value.

JSON

E.g.

var JsonDataobj =

[{

mobileCompany: 100000010,

mobileHandset: [

{value: 100000011,text: ‘Nokia 6.1’},

{value: 100000012,text: ‘Nokia 7.1’},

{value: 100000013,text: ‘Nokia 8.1’}

]},

{

mobileCompany: 100000020,

mobileHandset: [

{value: 100000021,text: ‘iPhone X’},

{value: 100000022,text: ‘iPhone 7’}

]},

{

mobileCompany: 100000030,

mobileHandset: [

{value: 100000031,text: ‘Samsung S8’}

]

}]

Now onLoad of Entity Form and onChange of parent Multi-Select option set we need to call below script.

Script

cascadingMultiOptionSet(executionContext): void {

/// <summary>

///  This function trigger on onload of form and onchange of Parent multi-option set field and set values of child multi option set field

/// </summary>

/// <returns type=”void” />

var functionName = “cascadingMultiOptionSet”;

var newChildOptArr = [];

var position = 0;

var newSelectedChildOpts = new Array();

try {

//JSON data retrieved from webresource

var parentChildCollection = JsonDataobj;

var formContext = executionContext.getFormContext();

//get parent’s selected  option values

var selectedParentOptValue = formContext.getAttribute(“ikl_mobilecompanies”).getValue();

//check if value selected or not

if (selectedParentOptValue != null && selectedParentOptValue.length > 0) {

//add value from parentChildCollection array to newChildOptArr.

for (var i = 0; i < selectedParentOptValue.length; i++) {

newChildOptArr = newChildOptArr.concat((parentChildCollection.find(x => x.mobileCompany == selectedParentOptValue[i])).mobileHandset);

}

//get all options from child option set

var existingChildOptValues = formContext.getControl(“ikl_mobilehandset”).getOptions();

//get selected options from child optionset

var selectedChildOptValue = formContext.getAttribute(“ikl_mobilehandset”).getValue();

var childOptCount = existingChildOptValues.length;

//remove options from child optionset

for (var i = childOptCount – 1; i >= 0; i–) {

//check if option is not selected or not present in newChildOptArr array then remove that option

if (selectedChildOptValue == null || selectedChildOptValue.indexOf(parseInt(existingChildOptValues[i].value)) <= -1 || (newChildOptArr.find(x => x.value == existingChildOptValues[i].value)) == undefined) {

//remove options from child options set

formContext.getControl(“ikl_mobilehandset”).removeOption(existingChildOptValues[i].value);

}

}

//set position of new element

position = selectedChildOptValue == null ? 0 : selectedChildOptValue.length;

//clear selected values from child option set

formContext.getAttribute(“ikl_mobilehandset”).setValue(null);

//add new options from newChildOptArr to child option set field

for (var i = 0; i < newChildOptArr.length; i++) {

//if value aready selected then don’t add that value

if (selectedChildOptValue == null || selectedChildOptValue.indexOf(parseInt(newChildOptArr[i].value)) <= -1) {

//addOptions with values and position

var optionSet = new Object();

optionSet.value = newChildOptArr[i].value;

optionSet.text = newChildOptArr[i].text;

formContext.getControl(“ikl_mobilehandset”).addOption(optionSet, position++);

}

//add previously selected option set to newSelectedChildOpts array

if (selectedChildOptValue != null && selectedChildOptValue.indexOf(parseInt(newChildOptArr[i].value)) > -1) {

newSelectedChildOpts = newSelectedChildOpts.concat(parseInt(newChildOptArr[i].value, 10));

}

}

}

else//if parent options not selected then clear child options

{

formContext.getAttribute(“ikl_mobilehandset”).setValue(null);

formContext.getControl(“ikl_mobilehandset”).clearOptions();

}

//set value of selected child option set

if (newSelectedChildOpts != null && newSelectedChildOpts.length > 0) {

formContext.getAttribute(“ikl_mobilehandset”).setValue(newSelectedChildOpts);

}

}

catch (ex) {

throw new Error(ex);

}

}

Result

1) If we select Nokia in Mobile Company Multi-select option set, then the Mobile Handset will bind only mobile handsets of Nokia.

Cascading of Two Multi-Select Option Set fields in Dynamics 365

2) If we select Apple and Nokia in Mobile Company, then both Apple and Nokia handset will be displayed in Mobile Handsets multi-select option set and the selected values of Nokia will remain the same.

Cascading of Two Multi-Select Option Set fields in Dynamics 365

3) If we remove Nokia from Mobile Company, then only Apple company handsets will be displayed in Mobile Handset multi-select option set and the selected options of Nokia handset will be cleared.

Cascading of Two Multi-Select Option Set fields in Dynamics 365

4) If the Mobile Company doesn’t contain any value, then Mobile Handset multi-select option will remain empty.

Cascading of Two Multi-Select Option Set fields in Dynamics 365

In order to see saved values of the multi-select option set for both parent and child it is necessary to trigger the above script function on a load of form.

Conclusion

We can achieve cascading of two multi-select option set from the above given script.

Click2Clone-One-Click-Productivity-App-to-Copy_clone-Dynamics-365_CRM-Records

2 thoughts on “Cascading of Two Multi-Select Option Set fields in Dynamics 365 v9.0

  1. krunal

    This code is not working on IE.
    IE does not support “=>”, JS is not loaded.
    Can you please guide me

    1. Inogic

      Yes, IE 11 does not support use of Arrow functions. Instead, it uses regular ‘functions’ as given below:

      Replace:
      var newChildOptArr = newChildOptArr.concat((parentChildCollection.find(x => x.mobileCompany == selectedParentOptValue[i])).mobileHandset);

      With this:
      var newChildOptArr = newChildOptArr.concat(parentChildCollection.find(function (x) {return x.mobileCompany == selectedParentOptValue[i];}).mobileHandset);
      and,

      Replace:

      (newChildOptArr.find(x => x.value == existingChildOptValues[i].value)) == undefined)

      With this:

      (newChildOptArr.find(function (x) {return x.value == existingChildOptValues[i].value;})==undefined)

      Hope this helps.

      Thanks!

Comments are closed.