JavaScript applied to Dynamics 365

Listed below are some examples of how I’ve seen JavaScript applied to Dynamics 365

JS ‘Common’ Code Snippets

Remove {} from a GUID
formContext.data.entity.getId().replace(/[{}]/g,'');
or
formContext.data.entity.getId().slice(1, -1);
Update a field that occurs multiple times on a D365 form
formContext.getAttribute(‘new_field1’).controls.forEach(
    control => { control.setVisible(false); }
);
Reloading a form after a Web API call returns successfully
...
req.onreadystatechange = function () {
    if (this.readyState === 4) {
        req.onreadystatechange = null;
        if (this.status === 204) {
            //Success - No Return Data - Do Something
            //May need to add a sleep function here to allow the Web API transaction to complete       
            Xrm.Navigation.openForm(entityFormOptions, parameters);
        } else {
            Xrm.Navigation.openAlertDialog(this.statusText);
        }
    }
};

JS Code Best Practices

Enumerated Types

Using enumerated types to make option sets more readable. For example

const ApplicationComplete = {
   Yes: 950000000,
   No: 9500000001,
   Pending: 950000002
};

...case ApplicationComplete.Yes:

rather than

...case 950000000:

Tools such as XrmDefinitelyTyped and Dataversify can connect to your Dataverse instance and automatically create these types

JS Callback

(Even though the callback design is now considered an old pattern, it’s still worth knowing.) According to w3schools, a callback is a function passed as an argument to another function. Carl has a good explanation of it here https://carldesouza.com/javascript-callback-functions/

The following code is an example of how to wrap a WEB API call using a JS callback. This helps if the same WEB API call needs to be made in several places within the code.

isUserInSystemAdminRole(function (isAssigned) {
    if (isAssigned) {
        //to something
    }
});

function isUserInSystemAdminRole(callback) {
    try {
        if (typeof callback != "function") {//throw error}
        var currentUserRoles = Xrm.Utility.getGlobalContext().userSettings.securityRoles;
        Xrm.WebApi.retrieveMultipleRecords('role', '?$select=name&$filter=contains(name, \'%Administrator%\')').then(
        function success(result) {
            var sysAdmin = result.entities.find(r => r.name.toLowerCase().includes("system admin"));
            var isSysAdmin = currentUserRoles.find(ur => ur == sysAdmin.roleid) == undefined ? false : true;
            if (isSysAdmin) {
                callback(true);
            } else {
                callback(false);
            }
        },
        function (error) {
            console.log('error retrieving user security role ' + error);
        }
    );
    } catch (err) {
        console.log(err.message);
    }
}

jXrm JS Library

As described in https://github.com/jasonxi/jXrm, jXrm was inspired by jQuery and it provides a JavaScript wrapping library on top of Microsoft Dynamics 365 (xRM) clientside SDK.

I’ve found that the biggest value add in using the library is in reducing the amount of code required.

jXrm attribute method .hide()
jXrm("#new_field1, #new_field2").hide(); 

instead of

formContext.getControl("new_field1").setVisible(false);
formContext.getControl("new_field2").setVisible(false);
jXrm attribute methods .disable() & .optional()
jXrm("#new_samplefield1, #new_samplefield2").disable().optional();

instead of

formContext.getControl("new_samplefield1").setDisabled(true);
formContext.getControl("new_samplefield2").setDisabled(true);
formContext.getAttribute("new_samplefield1").setRequiredLevel("none");
formContext.getAttribute("new_samplefield2").setRequiredLevel("none");
jXrm method .hideSection()
jXrm.hideSection(tab_general, sec_details);

instead of

formContext.ui.tabs.get("tab_general").sections.get("sec_details").setVisible(false);

Window object

  • window.document – contains the PCF controls
  • window.document.iframe – contains the forms’ js files
  • window.location – contains the server’s url e.g. href, origin
  • window.open – can be used to get around the CORS issue (note: this is a method)
  • window.parent – returns the parent window of the current window
  • window.top – returns the topmost browser window

References

1.) https://www.w3schools.com/jsref/obj_window.asp