Let’s agree to this. In any complex CRM implementations you would end up with lot of client side coding. No matter how much hard you try, you simply cannot avoid them. And why not. With new additions in CRM 2015, the client API of Dynamics CRM is as powerful as it ever was.
However believe me, they can be a nightmare to maintain and debug and if not maintained properly. And here I was in the same situation doing code review for some client. They had huge bunch of custom entities and jscript webresources and they named their scripts like this-
like for account, they have a single file named ‘account.js’. Similarly for opportunity – opportunity.js.
And all the code related to the that entity is stored in a single file be it the form events, custom ribbon button events, field events and what not. So whatever suggestions I provided, I thought of sharing with the community also since all this far my clients have been greatly benefitted by that approach and still I get a thank you note from them.
Well, then let’s start.
Suggestion 1
————————
Use namespaces in you jscript code like the way you use that in your Plugins and workflows. The biggest advantage of using namespaces is that even if you end up writing the same method in multiple jscript files and all those files are loaded by the browser at the same time, still they would be different since they would be qualified by their namespaces. So what is the convention?
So imagine you are doing some stuff for a company named ‘Constoso’. So the root namespace you can have as Contoso.
example:
if (typeof (Contoso) == “undefined”) {
Contoso= { __namespace: true };
}
Suggestion 2
—————————–
Keep a common helper file that can be used to write down all the utility functions that would be used across all entities and custom HTML webresources. I have seen that in projects with multiple developers working on the different modules, they tend to write up the same method as and when they require specific to the entity they are working. This results in loss of time and well as affects the re-usability and maintainability. A classic example would be something like – getUserRoles() and isUserInRole() methods. So instead of this you can do something like this.
- Create a webresource named Contoso.Utilities.js
- Then you can define the methods in the file like below.
if (typeof (Contoso) == “undefined”) {
Contoso= { __namespace: true };
}
Contoso.Utilities = {
_getUserInfo: function(){},
_isUserSysAdmin: function(){}
}
- You can then include the webresource wherever you need. To call the method of the file, you would need to use the fully qualified name
For e.g
var isAdmin = Contoso.Utilities._isUserSysAdmin();
- You can then direct all your developers to write any utility function, if not already present, in this file and not specific files for entity javascripts.
Suggestion 3
————————————
Name the files as per their intended functionalities. So lets take opportunity entity for an example. For opportunity you can have something like.
- Opportunity.FormEvents.js – This can be the place for all your form on-load and on-save events that you register for the form. So if there is any error you are getting during on save or on load of the form, you can be rest assured that the origin you can trace from this file.
- Opportunity.FieldEvents.js – Any field on-change events, tab state change events etc, you can place in this field. The good thing is if there is any error during on-change event of some field, you know which file to look into. Also if you follow a specific naming convention for you onchange events like for the customerid field on the opportunity, if you name the event handler like function customer_changed, you do not need to open the customizations and check what is the function name and what file the function is in.
- Opportunity.RibbonEvents.js – This can be very useful. If you place all the custom ribbon button event handler in this file, you no longed need to check the ribbon diff xml to find out which file the ribbon event handler is located in.
- Opportunity.Constants.js – This can be place to store all your constants that you need for the processing. in Plugins and workflows you can use the C# enums instead of hardcoding the values. But in jscript, if you want the same effect, you can just place it in this file.
And off-course not to forget, just backup the code for these files in appropriate namespaces.
Say for opportunity.formevents.js
if (typeof (Contoso) == “undefined”) {
Contoso= { __namespace: true };
}
if (typeof (Contoso.Opportunity) == “undefined”) {
Contoso.Opportunity = { __namespace: true };
}
Contoso.Opportunity.ForEvents= {
_formLoad: function(eContext){},
_formSave: function(eContext){}
}
And believe me, if you maintain you stuff like this, you would find it much comfortable to maintain and use in the long run.
Hope this helps!
Discover more from Debajit's Power Apps & Dynamics 365 Blog
Subscribe to get the latest posts sent to your email.