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