sharing a practice about massive changes on field appearance (visible, editable, mandatory) based on given rule(s) in Dynamics CRM

Hello,

I needed to implement complex rules for the fields on a form by actors,stages and status for one of my Dynamics CRM delivery.

for example;
"Actor (User) A" should be able to change Field1,Field2,Field3...FieldN but not see Section1, Section2, Section3... SectionN and maybe Tab1, Tab2, Tab3 ... TabN must be readonly for Actor (User) A as long as the form is under Stage X with Status C.

First of all, I define unique JSON object to cover fields rule which is going to be implemented in CRM Form. When a form is loaded, A client-side scripts will collect fields and rules than generate JSON object to push to the proper javascript method for making them visible, readonly or mandatory.

Here is the structure of  the JSON object;

{
 *      "requiredfields": {
 *              "controls": {
 *                  "name": [
 *                      // can be fields
 *                     "Field_1",
 *                     "Field_2",
 *
 *                     // can be sections
 *                     "Section_1",
 *                     "Section_2",
 *
 *                     // can be either tabs
 *                     "Tab_1",
 *                     "Tab_2"
 *                  ]
 *             }
 *          },
 *      "readonly": {
 *              "controls": {
 *                  "all": "none", // or "all" -- deprecated, do not use it !!!
 *                  "name": [
 *                      // can be fields
 *                     "Field_3",
 *                     "Field_4",
 *                     
 *                     // can be sections
 *                     "Section_3",
 *                     "Section_4",
 *
 *                     // can be tabs
 *                     "Tab_3",
 *                     "Tab_4"
 *                  ]
 *             }
 *          },
 *      "invisible": {
 *              "controls": {
 *                  "name": [
 *                      // can be fields
 *                     "Field_5",
 *                     "Field_6",
 *                     "Field_7",
 *                     "Field_8"
 *
 *                     // can be sections
 *                     "Section_5",
 *                     "Section_6",
 *
 *                     // can be tabs
 *                     "Tab_5",
 *                     "Tab_6"
 *                  ]
 *             }
 *          }
}


finally pass above structured JSON object with FormContext object to the below FormManagement.Initiate Javascript method.



/**
 * return control
 * @param {any} formContext
 * @param {any} element
 */
FormManagement.getControl = function (formContext, element) {
    if (formContext.getControl(element) != null) return new Array(formContext.getControl(element));
    else if (formContext.ui.tabs.get(element) != null) return new Array(formContext.ui.tabs.get(element));
    else return new Array(formContext.ui.tabs.get().find(elementTab => elementTab.sections.get().find(elementSection => elementSection.getName() == element)).sections.get(element));
}

/**
 * return control
 * @param {any} formContext
 * @param {any} element
 */
FormManagement.getControls = function (formContext, element) {
    if (formContext.getControl(element) != null) return new Array(formContext.getControl(element));
    else if (formContext.ui.tabs.get(element) != null) {
        var elements = new Array();
        formContext.ui.tabs.get(element).sections.forEach(elementSection => elementSection.controls.get().forEach(elementField => elements.push(elementField)));
        return elements;
    }
    else {
        var obj = formContext.ui.tabs.get().find(elementTab => elementTab.sections.get().find(elementSection => elementSection.getName() == element)).sections.get(element);
        if (obj != null) {
            var elements = new Array();
            obj.controls.get().forEach(elementField => elements.push(elementField));
            return elements;
        }
    }

}


FormManagement.Initiate = function (formContext, jsonObj) {
    try {
        // selected controls will be invisible
        jsonObj.invisible.controls.name.forEach(element => FormManagement.getControl(formContext, element).forEach(elementField => { try { elementField.setVisible(false) } catch (err) { console.log(elementField.getName() + ' is not valid control for visibility. Do not use ' + elementField.getControlType() + ' type of control '); } }));

        // selected fields will be read-only
        jsonObj.readonly.controls.name.forEach(element => FormManagement.getControls(formContext, element).forEach(elementField => { try { elementField.setDisabled(true); } catch (err) { console.log(elementField.getName() + ' is not valid control for readonly. Do not use ' + elementField.getControlType() + ' type of control '); } }));

        // selected fields will be mandatory temporary
        jsonObj.requiredfields.controls.name.forEach(element => FormManagement.getControls(formContext, element).forEach(elementField => { try { if (formContext.getControl(elementField.getName()).getVisible() && !formContext.getControl(elementField.getName()).getDisabled()) formContext.getAttribute(elementField.getName()).setRequiredLevel("required"); } catch (err) { console.log(elementField.getName() + ' is not valid control for mandatory . Do not use ' + elementField.getControlType() + ' type of control '); } }));

    }
    catch (err) {
        formContext.ui.setFormNotification(err.message);
        console.log(err.message + " - Stack : " + err.stack);
    }

}



Good Luck

Comments

Popular posts from this blog

Assembly Microsoft.Dynamics.Service.Plugins.dll can not be loaded. Dynamics CRM 365 Engine version 9 - CRM User creation error

Exception caught instantiating TERADATA report server extension SQL Reporting Services

Could not load file or assembly 'System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. The system cannot find the file specified at Configuration class initiation in CrmServiceHelper.cv