Naming your Web-Resource
Prefix_/EntityName/SpecificPurpose/[version].js
Few examples:
- msdyn_/SalesInsightsConfig/Resources/Globalization.1025.js
- new_/invoice/cancelAllContractNotificationOnRenewal.js
- msdyn_/solutionlayers/static/js/main.js
- new_/Quote/CreateDuplicateQuote.js
Note: It is important to consider having our own publisher where we can define our prefix to be used in all web-resource.
Commenting your Code
File comment to denote why, when and by whom its been created.
/********************** Source File Header **************************
Project Name: Clinic_ZZZZZ
Creation Date: 4th Feb 2018
Created By: vjCity \ Vipin Jaiswal
Last Modification Date: 27th Feb 2018
Last Modified By: vjCity \ Vipin Jaiswal
Version: 1.0.0.0
Purpose: Common JS Library
********************************************************************/
Going further in the blog you will notice how comments help us in understanding our code better.
Coding Style – Modular vs Object Oriented
When writing any helper class which is going to be used across all entities, I suggest going with Object Oriented way as we get a benefit of having our own namespace. There are two style of having object-oriented JavaScript code:
Explicit Namespace Declaration and using .(Dot) to have classification
// declare the default namespace
if (vjCity === undefined) {
var vjCity = {};
}
/// The cached user role
var cachedUserRole = new Array();
////////////////////Global Values////////////////////
vjCity.ERRORNotification = "ERROR";
vjCity.WarningNotification = "WARNING";
vjCity.INFONotification = "INFO";
//*******************Dialogs*************************
vjCity.changePasswordDialogId = "C3E7C5CD-AEF7-4DE7-8483-FBDF494F1A04";
vjCity.submitBusinessIdeaDialogId = "1A7A07C8-6B21-48DB-8BB4-1199451086E3";
//*******************Workflows***********************
vjCity.SubmitCommitteeDecisionsWorkflowId = "E2D77408-4A98-43D0-8856-ABEDEB8537D4";
vjCity.MembershipRequest_WorkflowId = "6F327E10-B358-4332-85F4-18D08C16F076";
vjCity.MembershipRequest_TransferToSupportWorkflowId = "5FDAA058-2301-43E6-B82E-7300339529E9";
/*
* Retrieve data
* Id = Id of the record
* type = Entity logical name
* select = fields to be retrieved ex: "new_A,new_B"
* callback = callback function
* example how to call this function :
***********************************************
var obj = Xrm.Page.getAttribute("exkb_client").getValue();
if (obj === null) return;
getDataById(obj[0].id, 'exkb_client', 'exkb_clientId, exkb_ClientContact', function(o)
{
if(!!o)
Xrm.Page.getAttribute("customerid").setValue([{id: o.exkb_ClientContact.Id, name:o.exkb_ClientContact.Name, entityType:'contact'}]);
});
***********************************************
*/
vjCity.getDataById = function (id, type, select, callback) {
var serverUrl = Xrm.Page.context.getClientUrl();
var oDataSelect = serverUrl + "/XRMServices/2011/OrganizationData.svc/" + type + "Set(guid'" + id + "')?$select=" + select;
var req = new XMLHttpRequest();
req.open("GET", oDataSelect, false);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json;charset=utf-8");
req.onreadystatechange = function () {
if (req.readyState === 4) {
if (req.status === 200) {
callback(JSON.parse(req.responseText).d);
}
}
};
req.send();
};
All Code within curly bracket ( { )
// declare the default namespace
if (vjCity === undefined)
{
var vjCity =
{
////////////////////Global Values////////////////////
ERRORNotification = "ERROR";
WarningNotification = "WARNING";
INFONotification = "INFO";
//*******************Dialogs*************************
changePasswordDialogId = "C3E7C5CD-AEF7-4DE7-8483-FBDF494F1A04";
submitBusinessIdeaDialogId = "1A7A07C8-6B21-48DB-8BB4-1199451086E3";
//*******************Workflows***********************
SubmitCommitteeDecisionsWorkflowId = "E2D77408-4A98-43D0-8856-ABEDEB8537D4";
MembershipRequest_WorkflowId = "6F327E10-B358-4332-85F4-18D08C16F076";
MembershipRequest_TransferToSupportWorkflowId = "5FDAA058-2301-43E6-B82E-7300339529E9";
/*
* Retrieve data
* Id = Id of the record
* type = Entity logical name
* select = fields to be retrieved ex: "new_A,new_B"
* callback = callback function
* example how to call this function :
***********************************************
var obj = Xrm.Page.getAttribute("exkb_client").getValue();
if (obj === null) return;
getDataById(obj[0].id, 'exkb_client', 'exkb_clientId, exkb_ClientContact', function(o)
{
if(!!o)
Xrm.Page.getAttribute("customerid").setValue([{id: o.exkb_ClientContact.Id, name:o.exkb_ClientContact.Name, entityType:'contact'}]);
});
***********************************************
*/
getDataById = function (id, type, select, callback) {
var serverUrl = Xrm.Page.context.getClientUrl();
var oDataSelect = serverUrl + "/XRMServices/2011/OrganizationData.svc/" + type + "Set(guid'" + id + "')?$select=" + select;
var req = new XMLHttpRequest();
req.open("GET", oDataSelect, false);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json;charset=utf-8");
req.onreadystatechange = function () {
if (req.readyState === 4) {
if (req.status === 200) {
callback(JSON.parse(req.responseText).d);
}
}
};
req.send();
};
};
}
Modular Approach to JavaScript
This is most straight forward way of coding and we can use this style when we are writing entity specific code and we just need declaration of methods.
An Example:
///
/*
Date created : 10 Jan 2018
Name : Vipin Jaiswal
Last updated : 13 Feb 2018
Purpose : JS Library for Applicant(Contact) Entity
*/
//****************** Global Value ******************************
var entityName = "contact";
var recordId = Xrm.Page.data.entity.getId();
//*************** Form Methods Start ****************************
function form_OnLoad()
{
SetDocumentFrame("IFRAME_documents");
CheckMembershipExpiry();
CheckEstablishment();
var val = Xrm.Page.getAttribute("address1_postofficebox").getValue();
Xrm.Page.getAttribute("address1_postofficebox").setValue(ValidatePOBox(val));
}
function form_OnSave()
{
}
//************ Ribbon Methods ***********************************
function changePasswordCallDialog()
{
//Call the change password dialog
Alert.showDialogProcess(changePasswordDialogId, entityName, recordId);
}
function bulkCreateCommitteeSessions()
{
// Call the bulk create committee sessions
Alert.showDialogProcess(bulkCreateCommitteeInstances, entityName, recordId);
}
//************* On Change Methods *************************
function EmploymentStatusOnChange() {
CheckEstablishment();
}
function EmariteIdOnChange() {
ValidateEmiratesId(Xrm.Page.getAttribute("kfexc_emiratesid").getValue());
}
function PassportExpiryDateOnChange() {
var passportExprity = Xrm.Page.getAttribute("kfexc_passportexpirydate").getValue();
if ((passportExprity !== null || passportExprity !== undefined) && vjCity.dateIsLater(Date.now(), passportExprity)) {
vjCity.showFormNotification("Passport is Expired", vjCity.WarningNotification, "1");
}
else
vjCity.clearFormNotification("1");
}
function BirthdateOnChange() {
var birthdate = Xrm.Page.getAttribute("birthdate").getValue();
if ((birthdate !== null || birthdate !== undefined) && vjCity.dateIsLater(birthdate, Date.now())) {
vjCity.showFormNotification("Birth Date is in the future", vjCity.WarningNotification, "3");
}
else
vjCity.clearFormNotification("3");
}
function MobileNumberOnChange() {
var mobNumber = Xrm.Page.getAttribute("mobilephone").getValue();
}
function HomeNumberOnChange() {
var Number = Xrm.Page.getAttribute("address1_telephone1").getValue();
vjCity.ValidateMobileNumber(Number, "address1_telephone1");
}
//
//*************** Business Validation Methods **************
function ValidateEmiratesId(txt) {
if (txt === "")
return;
var patt = new RegExp("^[0-9]{15}$");
var res = patt.test(txt);
if (!res || !txt.startsWith("784")) {
vjCity.showFieldNotificiation("kfexc_emiratesid", "Emirates Id format is invalid");
}
else {
vjCity.clearFieldNotification("kfexc_emiratesid");
var a = "";
for (var i = 0; i < txt.length ; i++) {
switch (i) {
case 2:
a = a + txt[i] + "-";
break;
case 6:
a = a + txt[i] + "-";
break;
case 13:
a = a + txt[i] + "-";
break;
default:
a = a + txt[i];
}
}
Xrm.Page.getAttribute("kfexc_emiratesid").setValue(a);
}
}
function ValidatePOBox(val)
{
if (val !== undefined && val != null)
return val.replace("-", "");
return "";
}
I hope there are better approach to have perfect coding style, please do let me know if you came across any in comments.
Thanks,
Vipin Jaiswal
vipinjaiswal12@gmail.com