Dynamics 365 – Problems debugging fields on a form

“ If debugging is the process of removing software bugs, then programming must be the process of putting them in. ” – Edsger Dijkstra

Dynamics 365 is a place where only dirty entities and fields are saved! The clean fields are ignored #HoskCodeWisdom

  • Junior developer – assumes how things work
  • Good developer – finds out through trial and error
  • Great developer – does not assume and methodically confirms

Dynamics 365 can frustrate developers (The Frustrations of a CRM Developer), developers are provoked by the idiosyncratics, limitations and bonkersness of Dynamics 365 as Microsoft works on new ways to annoy developers 🙂

Bugs and problems areopportunities to gain a deeper knowledge of the workings of Dynamics 365.

New developers get caught out such as in the CRM 2011 (good old) when SetSubmitMode was a rite of passage for Dynamics CRM developers – CRM 2011/2013 – What does setSubmitMode do? and how does it work?

Unless you made the field dirty and change SubmitMode the field was not sent to the database to be saved

Try, Try and try again

On creation of an appointment the start and end times should be editable, on a form update those fields should be readonly.

Examples of using the SetDisabled(true) were found in the code, copied and adapted for the start and end times on the appointment entity.

He kept debugging and being puzzled because the start and end times were not changing, but why not?

Insanity: doing the same thing over and over again and expecting different results.  Albert Einstein

Developer Insanity: Testing the same code over and over and expecting intermittent result #HoskCodeWisdom

Hosk developer debugging beliefs

  • Investigate bugs with an empty mind
  • Microsoft 365 is full of quirks which make sharing knowledge between team members important
  • Bugs are not a sign of a bad developer, they are a sign of a developer developing #HoskCodeWisdom
  • Always help your fellow developers, big projects need a strong team.  Never leave a developer stranded
  • Don’t suffer in silence if you are not making progress, get help and get direction #HoskWisdom

SetDisabled = true

The way to make a read-only field editable is to use the Dynamics 365 JavaScript Xrm, get the control and use the setDisabled(false)

Xrm.Page.ui.controls.get(“your field name”).setDisabled (true); //Field readonly you can’t write any thing on field

if you change true as false;

Xrm.Page.ui.controls.get(“your field name”).setDisabled (false); //Anyone can put value on this field

I looked at the code, it looked fine, we checked a few things

  • Is there any other code changing the field back to read only –> No
  • Checked the line worked in the debugging console –> Yes
  • Was there a JavaScript error –> No
  • Debug the code, does it run the line of code which enables the field –> Yes

Appointment entity

In this example we used the appointment entity, which is an odd entity.  It‘s not possible to add new forms for the appointment entity Dynamics 365 – You can’t add new forms to the appointment entity There is code running on the appointment entity which a CRM developer has no control over, cannot see and cannot edit.

When you book appointment it sets the user who booked the appointment as the organizer of the appointment.  This is fine for Outlook but not what I wanted to happen in Dynamics 365.

Adding hidden custom code which developers can’t disable is frustrating as much as it is undocumented, believe Microsoft should write customizations in the same way standard Dynamics 365 developers do. This would allow us to see, modify, disable or extend the default behavior.

Stop, think

When you rule out the obvious, it’s time to check the stupid – #HoskWisdom

Appointment entities don’t allow you to add new forms (or change the status/status reason of the appointment) because we couldn’t add new forms, we had JavaScript which when the regarding field was set to a specific custom entity we disabled the default section and showed a new section with custom fields on.

Usually a developer would create another form but we couldn’t because it was the appointment entity

This resulted in the same fields being on the form twice, the start and end times.  So the code was working, except it was making the fields on the hidden section and the first fields on the form.

To resolve the problem go to the section (in code) and then retrieve the field you want and then make it make it editable.

Hosk values with bug fixing

  • Developers who fix a problem which doesn’t keep popping back because it‘s not properly fixed
  • Developers who use a bug as an opportunity to learn how Dynamics 365 works
  • Developers should try to resolve the problem first before asking for help
  • Don’t spend too long being puzzled by a bug before asking for help, Dynamics 365 has odd quirks and limitations which can take hours to resolve.  Get direction from a colleague after 1 hour of frustration
  • Developers should not assume, they must clarify (I wasted hours looking in the wrong place because I didn’t check my assumptions)

On a separate note but relatedish – Developers using JavaScript onload should be careful when setting and changing values because it can frustrate user by asking them to save a form when they haven’t change any values When to automatically change fields using Javascript 

picture from here

Advertisement

CRM 2015 – How to set focus in Javascript

I wanted to set focus in Javascript after a user had changed a field to yes, this triggered an onchange event.  The onChange event set a new tab to be visible.

The new tab was below and the users didn’t always know it was there, so I wanted to nudge them in the right direction by setting focus on the tab.

Microsoft has added a great framework for manipulating the controls.  The Javascript for setting focus works on the Control level

Xrm.Page.getControl(arg).setFocus()

Xrm.Page.ui.tabs.get(“tab_schemaName”).setFocus();
Xrm.Page.getControl(“ntt_reviewteamid”).setFocus();

This blog post has a great page, it highlights the functionality available in the CRM SDK, displaying the logical structure of the JavaScript wrapper created for development

Microsoft Dynamics CRM 2013: Client API Enhancement

 

Different Versions

It’s important to check the CRM SDK XRM documentation because each release of CRM adds and removes functions.

Xrm.Page.ui control (client-side reference)

The CRM SDK documentation shows the functionality available for each release by selecting the CRM version in the drop down at the top of the page.

Javascript versions

When you select a different version it will change the methods available.  This enables you to see what functionality is available for each version and what new functionality has been added.

CRM 2015/CRM2013 – JavaScipt to get the current users name

This blog post will show you a quick way to get the name of the user using JavaScript.

Where you might use this functionality

This functionality is useful because you might need to update a User lookup field to a particular user in situations like

  • The current user changed a key field
  • The current user is primary contact for a project, account, deliverable.
  • Set a text field of the users name for reporting purposes.

Why are you mentioning it

To do retrieve the current user name in CRM 2011 it took a soap call to retrieve the user name field using the Xrm.Page.context.getUserId().  Below is a blog post I wrote

CRM 2011 – Setting a user lookup with the logged in user with Javascript

There is now a much easier way to do this in CRM 2013 and CRM 2015.  I found this way whilst reading this forum post

crm 2013: javascript get attributes from other entity in Contact Form

Start with the CRM SDK

The Hosk CRM developer mantra is to always start with the CRM SDK to see what methods and functionality exists which can help.

Searching the CRM SDK first helps you see what functionality Microsoft have added, most CRM developers will be surprised the number of new methods added.

It’s very easy for developers to copy and paste existing code in projects but just because it works it doesn’t mean its the best code to use.

This is classic case, the CRM 2011 code is long and involves a soap call, the new functionality added in CRM 2013 allows you to access the data with one line.

Microsoft Client code page – Client-side context (client-side reference)

There are three useful functions about the existing user (there’s another about language but I’m not including it).

getUserId
Returns the GUID of the SystemUser.Id value for the current user.
getUserName
Returns the name of the current user.
getUserRoles
Returns an array of strings that represent the GUID values of each of the security roles that the user is associated with or any teams that the user is associated with.

 

Xrm.Page.context.getUserId()

This would get you the SystemUser.Id

Xrm.Page.context.getUserName();

This would return a text string of the user name

Setting User lookups

The common reason for retrieving the user name and the user id is because both values are needed if you want to programatically set a lookup field in CRM.

Example code is shown below


var setUservalue = new Array();
 setUservalue[0] = new Object();
 setUservalue[0].id = Xrm.Page.context.getUserId();
 setUservalue[0].entityType = 'systemuser';
setUservalue[0].name = Xrm.Page.context.getUserName();

Xrm.Page.getAttribute("LookupField").setValue(setUservalue)

Alternatives

In the requirement I was working on I used JavaScript because I needed to set a field dynamically and instantly.  Other CRM customizations may have different requirements and you could set the lookup field using a Plugin or a workflow.

What I have learnt

  • Use the CRM SDK to see what functionality exists, there might be a better way
  • Microsoft added a new getUserName method in CRM 2013
  • You need the guid, name and entity type to set the value of a lookup field
  • If you don’t need to set the lookup instantly you can use workflows or plugins
  • CRM forum posts provide extremely useful information from a number of CRM developers

 

CRM 2013 – Javascript null setting oddity

I had an odd error where I was trying to null a lookup field in Javascript in CRM 2013 Service SP1.

When the user changed a lookup field, I wanted to blank out a few fields to make them select those fields again.  The fields being nulled were dependant on selection of the first lookup field and the options and values they could pick changed.

It’s good practise to reduce the number of choices users have by filtering out values in option sets and lookups, hiding/showing fields.  This makes the forms more cohesive, less noise for the end users.  Read more about CRM Form design in the article below

Good CRM design should not make users think

The initial code was in a function and looked like this

        if (Xrm.Page.getAttribute("field1").getValue() != null) {
            Xrm.Page.getAttribute("field1").setValue(null);
        }


        if (Xrm.Page.getAttribute("field2").getValue() != null) {
            Xrm.Page.getAttribute("field2").setValue(null);
        }
        

Oddly field1 was correctly set to null but field2 refused to be set to null.

To add to the annoyance of not setting the field to null, the not nulling triggered the OnChange event for the lookup which set other values on the previous not nullable value!!!

This made me angry

Stepping through

When bug fixing the goal is understand exactly what is happening, once you understand what is happening it might be possible to work out why or work around it.  There is a big difference between

  • Knowing what is happening
  • Your assumptions about what is happening

Assumptions are dangerous because they can easily be wrong.  When bug fixing don’t assume anything and prove everything.  I have wasted plenty of time with assumptions and investigating the wrong section of code.

I started debugging and stepped through the setting the values to null.  The handy part of debugging JavaScript is the console allows you to integrate the values.

The values on the GUI looked like fields1 and fields2 were both not being set to null.

I debugged and stepped through the code, field2 wasn’t being set to null but the OnChange event was running for field2 which was setting field1 and field2 to the values based on the previous field2 value.

One change at a time

One of the golden rules when debugging a problem is to change one thing at a time, monitor the effects of the change.  This rule is particularly inportant if the change is a configuration change which will be changed on multiple environments (DEV, TEST, PREPROD, PROD).

When changing values or code, making a solitary change will show you the effects of the one change.  If you change 5 things at once which resolves the problem, you don’t know what change has fixed the problem.  In the multiple change scenario you would either need to go back and change one variable at a time or make all the changes in all the environments.

When making changes to code/config it’s good practise to minimise the changes, which minimises the potential unknown effects of these changes and reduces bugs coming from these changes less likely.

I tried

  • removing field1 change
  • swapping the order, changing field2 before field1
  • double checking javascript
  • Asking fellow CRM developers

Asking fellow CRM developers did bring a few mumbles of maybe having seen something like it before but no one could remember what is was or what they did (if only they wrote a blog post about it!!)

None of the other changes did much.

To the Internet

 

Searching the internet didn’t bring up anything directly relevant (how often does that happen!), it did lead me to this page

Javascript, onChange events no longer work on an empty field

This wasn’t the problem I was experiencing

I just noticed that if you have a form field that triggers a Javascript function on the onChange event it no longer triggers the function if you clear the field, but ONLY when you change the field data. For instance; if you have a Name field populated with a name, and you remove the name – the function isn’t triggered. It’s left empty. You have to change the text inside the field.

 

The problem being talked about here is setting required fields to null didn’t trigger the onchange.  I had this reverse of this problem I was setting field2 to null, it wasn’t setting but triggering the OnChange, which means Microsoft fixed the problem report (the forum posts were Feb 2014).

The forum post go me thinking, lets change the field requirements and see what happens.

Setting field requirements using Javascript

Fields have three levels of requirements

  • none
  • required
  • recommended

For some reason accessing these programmatically seems quite different from setting/adjusting them using the GUI.  Looking at the list what is the point of recommended, it should be required or none.  Why you would want to change a field to have a requirement level of recommend?

The code is string based, which seems a little odd and prone to syntax errors.  To find all the Javascript methods use this page on the CRM SDK

Xrm.Page.data.entity attribute (client-side reference)

Here is an example using the trusty field2

  • Xrm.Page.data.entity.attributes.get(“field2”).setRequiredLevel(“none”);
  • Xrm.Page.data.entity.attributes.get(“field2”).setRequiredLevel(“required”);
  • Xrm.Page.data.entity.attributes.get(“field2”).setRequiredLevel(“recommended”);

I changed my code to set the required level to none, set field2 to null and then reset the required level to required.

//I had to set required level to none because assign null wasn't working, might be fixed in future roll ups
	if (Xrm.Page.getAttribute("field1").getValue() != null) {
            Xrm.Page.getAttribute("field1").setValue(null);
        }

        Xrm.Page.data.entity.attributes.get("field2").setRequiredLevel("none");
        if (Xrm.Page.getAttribute("field2").getValue() != null) {
            Xrm.Page.getAttribute("field2").setValue(null);
        }
        Xrm.Page.data.entity.attributes.get("field2").setRequiredLevel("required");

Leave a comment

If you have written some unusual code as a work round for a limitation in design or a known bug, it’s good practise to leave a comment explaining to other developers (and maybe your future self) why you have put the code.

Reasons why you should comment unusual code

  • A developer could easily delete the code without realising what is meant to do
  • It could be confusing for other developers to read and understand
  • A rollup/service patch might fix the code and it could be safely removed
  • The developer reading the code might know the solution to this problem
  • It’s good practise

CRM 2013 – Disabling a subgrid

This blog post will look at possible ways to disable subgrids in CRM 2013.  I had a requirement if a user made a case restricted then the case couldn’t be linked to any other cases.

Requirements

  • On the case form we had functionality to select a parent case and a subgrid to add child cases.
  • Case had a restricted bool field
  • Restricted cases could not link to any other cases

If the user set restricted to Yes I had to disable the subgrid and the case lookup, e.g. stop the restricted case from being linked

Disabling the case lookup field was was straightforward

  
Xrm.Page.getControl(fieldName).setDisabled(true);
	

Frustratingly for me subgrid control does not have a setDisabled method, this means disabling the subgrid would not be as straightforward.

Disabling a sub grid

This is a different story, a story with twists, frustration

An unsupported way

http://www.magnetismsolutions.com/blog/paulnieuwelaar/2012/02/28/Disable_Subgrids_with_Javascript_in_Dynamics_CRM_2011.aspx

  
// Disable a subgrid on a form
function disableSubgrid(subgridName) {
document.getElementById(subgridName + "_span").disabled = "true";
}
	

I’m not going to consider putting in unsupported changes because if you do then Microsoft will unsupport your customizations.  This probably doesn’t sound like much of a threat but if you find a bug with out of the box functionality Microsoft won’t even look at your customizations due to the unsupported code.  When the customer then finds out they have no Microsoft support because of your code.

Why you shouldn’t put unsupported customizations in Microsoft Dynamics CRM

From the Hosk Wisdom page 🙂

Don’t even think about making unsupported changes in CRM because Microsoft will un-support your CRM if they find out – Hosk

Don’t do unsupported CRM customizations, 99.9 percent of the time there is another way.  For the 0.1, tell the customer its unsupported – Hosk

Other Options

If I can’t disable the subgrid (in a supported way), what other options do I have?

Disable buttons on subgrid

Scott Durow the Ribbon Workbench creator has an excellent article on disabling the add new button.  This hiding rule could be set on all the add buttons on the subgrid.

Show or hide the ‘Add New’ button on form sub-grid based on the value on the form

It’s worth reading this article just to look at the image which explains what buttons on the sugrid link to what buttons on the command bar inside the Ribbon Workbench.

In theory this option should work but it would involve setting up enable rules for all the buttons on the subgrid.

Hiding and Showing

Hiding and showing sounds like a kids TV show, actually I’m thinking of Show me Show Me

My initial thought was to disable the grid but in CRM 2013 sub grid doesn’t have a setDisable, which stopped my plan but looking at the CRM SDK I can see subgrids control does have a setVisible.

This line of supported code will hide the subgrid 

Xrm.Page.ui.controls.get(controlName).setVisible(false);

This shows it again

Xrm.Page.ui.controls.get(controlName).setVisible(false);

The code above worked and it did hide the subgrid, the problem I had was it looked odd because it left a big blank white space where the sub grid was hiding (not very well).

The other problem is sub grids load asynchronously.  I needed my code to work on the form OnLoad event but when it came to hiding the the subgrid it was loaded yet and would throw an error.

To get round this error, I would need to wait until the subgrid had been loaded, so I could subsequently hide it (which doesn’t seem right when I say that out loud)

I created this code to wait until the subgrid is loaded.

  function ShowSubgrid(show) {
        var Subgrid = Xrm.Page.ui.controls.get("ChildCasesGrid");

        if (Subgrid == null) {
            setTimeout(function () { ShowSubgrid(show); }, 2000);
            //if the grid hasn’t loaded run this again when it has
            return;

        } else {
            if (show) {
                ShowControl("ChildCasesGrid");
            } else {
                HideControl("ChildCasesGrid");
            }
        }
    }
	

This works but I don’t like having wait’s in code, particularly in a form load where you don’t want to add an extra lines running on a form load which usually takes a while and the form load performance is extremely visible to a user.

I am of the opinion to avoid waits in the code at all costs, if you have a wait in the code you have a bug/problem waiting to happen.  Most of the time its worth the effort to find an alternative solution and reduce the complexity of your code.

A wait in code is similar to seeing +1 in some code.  The code is working round a problem rather than resolving the cause.

When considering form loads in CRM, it’s probably comparable to the frustrating time it takes for a computer to boot up in the morning.  The time may only be a short amount of time but it feels about four times as long in real time.

Whilst a form is loading the user has nothing to keep them occupied so the time feels longer, try to keep forms loads as quick as possible.  Here is a blog post I wrote on performance issues

CRM 2011/2013 Investigating CRM Form Performance issues

QUICK BREAK TO LOOK AT CRM 2015 SP1 new GridControl stuff

Looking at the CRM SDK form events page, initially it loads the latest page for CRM 2015 and I noticed CRM 2015 SP1 has a new special Subgrid OnLoad event.

There is a new page Write scripts for subgrids, there is now a new GridControl and you can look Grid objects and methods to see the new cool things you can do

The Grid Onload method is cool but there are some other interesting methods I noticed

The grid has

  • getRows
  • getSelectedRows
  • getTotalRecordCount

From the Grid you can get do a getRows and from here there are some great helper methods in the GridEntity

  • getEntityName
  • getEntityReference
  • getId
  • getPrimaryAttributeValue

and other stuff which you should go and check out yourself

Back to CRM 2013 subgrids

After some developer brainstorming I decided to try putting the subgrid into a section.  The advantages of this is you can hide/show a section without having to wait for the form to load.

Another advantage is when you disable a section it hides itself much better, the form acts as if it wasn’t there at all, unlike hiding the subgrid which leaves a white space the same size as the subgrid.

To hide or show a subgrid you have to toggle the visible flag using the setVisible method

Hide

Xrm.Page.ui.tabs.get("tabName").sections.get("sectionName").setVisible(false);

Show 

Xrm.Page.ui.tabs.get("tabName").sections.get("sectionName").setVisible(true);

Plugin Option

Maybe the most straight forward to resolve this issue is to have a plugin which is triggered on change of parentCase field.  When setting this you could check to see if the child or parent case is a restricted case and throw a pluginException

Conclusion

The blog’s title is about disabling a subgrid but the goal was to stop restricted cases from being linked.

The benefit of Javascript customizations is they are instant because the code works on the client side.  Plugins are server side, so their is a delay in capturing and responding to the changes.

Javascript can often offer a better user experience because CRM developers can react instantly to changes in values and hide/disable fields.

Server side changes are less responsive and cannot guide the user in the same way Javascript validation code can but has to catch the values and decide whether to roll them back.  Server side validation can be more frustrating to CRM users because they have made the changes, only to find them being rejected.

In this scenario the plugin/server changes are in one place, where there are lots of Javascript code changes to do the same thing.

A key skill of a CRM developer is selecting the right customization for the right job

CRM 2015 SP1 – Turbo forms use asynchronous JavaScript web resource loading

I was reading this blog post from the CRM Lady

Turbo Forms in Microsoft Dynamics CRM 2015 (v7.1.0)

The article points to some good resource learn more about the new turbo forms.

The article from the CRM Team has a wealth of interesting information and lots of healthy warnings for you

Microsoft Dynamics CRM Online 2015 Update 1 – New Form Rendering Engine

What are the new turbo form

Microsoft have been doing lots of tinkering how the CRM forms are rendered.  This graphic shows the effect

// // // // // //

When I saw the graph above my first thoughts were

  1. WOW, Awesome
  2. How did they get such a dramatic improvement
  3. Will this break my customizations

How did Microsoft Improve loading times

I will quote the article

There are 2 main changes that have been made: loading process of the form, and handling of cache.

The article indicates they have moved to parallel loading and are caching more data.

 

Hmmmm Parallel Javascript loading

The increased form loading is great but parallel loading can have some downsides.  I first came across Javascript parallel loading in CRM 2011 rollup 12, you can read about here

To speed up form loading in CRM 2011 they switched to parallel loading and the result meant lots of Javascript methods suddenly stopped working.  The reason for this was because one Javascript file was calling a method on another javascript file.  This worked when the Javascript files were loaded in an order but when you load them all at once sometimes one Javascript file tries to call another dependant Javascript file which is still loading.

So suddenly lots of Javascript errors appeared and all developers had to write a Javascript wait file, like CRM MVP Scott Durow talks about in this article

This is a significant change and could cause lots of errors if you have Javascript code in your OnLoad functions which call other Javascript files.

I noticed a new section appeared in the mdsn article Write code for Microsoft Dynamics CRM forms

Manage library dependencies

As a performance optimization, Microsoft Dynamics CRM forms load JavaScript web resources asynchronously and in parallel. This means that the order in which the libraries are configured for a form does not guarantee that a library will be fully downloaded and initialized before another library might attempt to use one of the objects defined in it.

If you have code that depends on another library to be fully downloaded and initialized, the most straightforward approach is to combine both libraries within a single JavaScript web resource with your code below the library code. A more sophisticated approach is to use libraries such as head.js or require.js to control how the separate libraries are loaded.

 

Is Parallel loading good or bad

There is a quote in blade runner

Replicants are like any other machine. They’re either a benefit or a hazard. If they’re a benefit, it’s not my problem.

Upgrading to CRM 2015 SP1 could cause big problems to Javascript customizations.  It’s good practise to split up your Javascript code to separate files to make it reusable and maintainable but now Microsoft are recommending we put everything in one file.  This could turn out to be one big massive Javascript file, which is ok for performance but maintaining and working with this file is difficult.

This change could catch many CRM developers out because the errors are intermittent, sometimes the javascript files will have loaded in the correct order and work.

It will involve developers writing Javascript code which waits until all the Javascript files load which will cancel out any benefits from parallel loading.

It could be seen as an opportunity to restructure Javascript code to have a self contained loading script and then move other Javascript functions to OnChange events.  This would be a double win of increased loading time due to parallel loading and running less code.

You can use Legacy form loading style

There is a system setting which contains a global setting to control which form loading style you use.

It’s a great idea for Microsoft to put this in because the new speedier form loading code might take some while getting use to it.  When CRM 2011 polaris release came it, it caused a raft of blog posts because CRM Javascript customizations suddenly stopped working.

Settings -> Administration -> System Settings -> General. Select “Yes” under “Use legacy form rendering”

In a perfect world it would have been great to have a entity setting rather than a global setting for the form rendering.

I thought I would write about this because it could effect a lot of people and I never spotted this change until today.

 

What is the !! Javascript operator!!!!

I saw some Javascript code which the CRM Developer Pacman was working on and it had a bizarre If statement which used a double exclamation mark!!

One exclamation mark means not but what does two exclamation marks mean Not Not?

Below is the code in question

var roleName = null;
$.ajax({
    type: "GET",
    async: false,
    contentType: "application/json; charset=utf-8",
    datatype: "json",
    url: odataSelect,
    beforeSend: function (XMLHttpRequest) { XMLHttpRequest.setRequestHeader("Accept", "application/json"); },
    success: function (data, textStatus, XmlHttpRequest) {
        var result = data.d;
        if (!!result) {
            roleName = result.results[0].Name;
        }
    },
    error: function (XmlHttpRequest, textStatus, errorThrown) {
        //alert('OData Select Failed: ' + odataSelect);
    }
});

The code was doing an OData query and then checking the result with the if Statement

if (!!result) {

      roleName = result.results[0].Name;

}

What does the !! exclamation do

It’s quite clever because the first exclamation mark converts the object into a boolean value, the second exclamation mark checks to see if the boolean is false.

In C# developer terms its like casting the object to a boolean and then doing an inverted check (e.g. if not false)

This two Stackoverflow articles discuss and explain the !! exclamation in more detail but this answer and the truth table helped me understand

Double Exclamation points

''        ==   '0'           // false
0         ==   ''            // true
0         ==   '0'           // true
false     ==   'false'       // false
false     ==   '0'           // true
false     ==   undefined     // false
false     ==   null          // false
null      ==   undefined     // true
" \t\r\n" ==   0             // true

Using the table above my understand is the !! exclamation in the examples checks to see if the result object is not 0, undefined, null because all those values would be converted to a boolean type of false.

Here is another good discussion on the topic

What is the !! (not not) operator in JavaScript?

Whilst researching this topic I found the article below

Truthy and falsy in JavaScript

The article talks you understand how Javascript uses true, truthy, false and falsy in JavaScript

 

How to find Javascript files used in Microsoft Dynamics Forms

Sometimes when you work on a CRM project which contains lots of Javascript files, it can be difficult to determine what Javascript files are being used and which ones are still needed.

The route cause of this is Microsoft Dynamics CRM forms can have lot of methods triggered from fields or ribbon buttons but these can be difficult to find to find what Javascript files are being used.

Where is Javascript triggered in CRM

Javascript files can be used on CRM forms and the code can be triggered on forms loading/saving or by the OnChange event of a field and the Ribbon buttons.  Below is where Javascript files can be used in CRM

  • Javascript triggered by OnChange events
  • Javascript triggered by Ribbon buttons
  • Javascript triggered in form OnLoad/OnSave events
  • Javascript files used in html pages

There are many different areas Javascript can be used but it can be difficult to see what Javascript files are used and linked to field OnChanges, ribbon buttons.

One of the reasons this is difficult is because the CRM UI means it’s not easy to see what fields have Javascript functions triggered via the OnChange event and the only way is to either look at the Javascript files and hope the CRM Developer has used a logical naming structure.

or

You can click the fields in the CRM form and check if there is an OnChange event.

Javascript development and deployment

Javascript development and Javascript deployment can be a bit disjointed.  One method is to write the Javascript file in Visual studio then you copy the Javascript file and paste it into the CRM form changes, save and publish.

It should be noted this isn’t a new problem for CRM 2015/2013 , there have been lots of tools created to help the process.

CRM MVP Mitch Milam created the export Javascript file tool, which I hada used in older versions of Microsoft Dynamics CRM, which you can read about here

The Microsoft Developer toolkit brought big improvements which allowed you to deploy/update Javascript file changes from Visual studio.  I go through the process in this video from Hosk CRM Dev Youtube channel

What Javascript files are used

I recently worked on a project which had gone through some optimization and refactoring, my current task is finding out if all the Javascript files are needed for each of the forms.

The reason the project is in this state is we quickly needed to optimize the code and whilst doing this the Javascript was optimized and refactored, this has resulted in some of the Javascript files not being needed

The code was refactored but some of the Javascript files which were no longer used were not removed.

The code was also part of the Async Javascript load issue, which happened in CRM 2011 Rollup 12

CRM 2011 – Things learnt when reviewing Javascript code on form loads

Here is my blog post on CRM form performance

CRM 2011/2013 Investigating CRM Form Performance issues

 

The Problem

Tidy up Javascript files on forms, remove the WaitForScriptsLoaded Javascript file and replace the onload method with the entity Javascript file.

Remove Javascript files which are no longer referenced.

Factors

To make the problem harder, the Javascript was split over 10 different Javascript projects, which made find if Javascript files were used

To help me the project adhere’s to Javascript best practices and uses Javascript namespaces.

link to Javascript namespaces

Things to consider

When looking at what Javascript files are needed don’t forget to check the Javascript files used for the ribbon buttons, in this particular project most forms had 5 custom ribbon buttons.

Tools used

Fiddler

I used Fiddler to track what calls were being made out of the form

Visual Studio

I used Visual studio to look at the Javascript files included on the FORM.

F12 Debugger

Press F12 on a record and I could see all the Javascript files being used.

Script finder tool

I knew there was a script finder tool but I couldn’t find it when searching the internet.  Thankfully a reader added a comment and of course it’s in the everyone’s favourite CRM tool or collection of Tools the XRMToolbox.

The XRMToolbox has a Script finder tool which will list all the Javascripts and will show the event e.g. OnLoad, OnSave, OnChange as you can see from the screenshot below

image_24 (2)

 

The tool looks great but I would say the project I was working on has a lot of Javascript and when I tried I pressed the find scripts button it never came back.  I think it timed out because there are loads (hundreds) of scripts and functions.

Process of finding unused Javascript files

I did try doing a find in files but this proved to be very slow and seemed difficult, I eventually decided this process wasn’t really working.

So I looked at the problem a different way

How do I find what files are used when the CRM form is being used?

 

I came up with two main methods.

Method 1

Go through the main Javascipt file specified in the form onSave/OnLoad and look what other Javascript files/methods are referred.  Thankfully the Javascript files used were developed with using Javascript Namespaces so I could search for the namespaces in the file to see what other Javascript files were used.

I cold then compare the Javascript files listed in the Javascript files for the form and what Javascript files were referenced in those Javascript files.

Method 2

When the Javascript form is being used in CRM you can press F12 to get the debugger up, I  could see what Javascript files are loaded.

 

Why did this happen

Good CRM Development will mean the CRM developer will create lots of seperate Javascript files which can used in multiple CRM forms.  The reason you split the Javascript file into common Javascript files is because it’s better to use the same Javsacript code in many different forms rather than copy the code in many different Javascript files (e.g. if you have one Javascript file for each form).

You never want to duplicate code because if there is a bug in the code then you would have to fix all the various copies of the code and the chances are you would forget to change some of them.  Later it would be difficult for the CRM developer to know which code was fixed and which code still had the bug in.

When Javascript code is no longer needed CRM developers often forget to remove Javascript files and methods, this can add to the confusion for a CRM developer when there are javascript files and methods which don’t seem to be used.  It can be scary to be the CRM developer to remove unused Javascript files and methods because it’s difficult to be 100 percent sure they are not used anywhere.

 

 

 

 

Beware of the Bad Javascript for loop

I should have written this blog post on halloween, wooooooo but I hadn’t seen the bug then so that would involve time travel and I haven’t got time for that.  Wait if I invented a method of time travel I would have all the time I would need.  Oh no another bad loop I have got myself in.

Yesterday I blogged about an error I had with a for loop, you can read it below

CRM 2011/2013 – What does setSubmitMode do? and how does it work?

 

This was the code that caused the problem

var attributes = Xrm.Page.data.entity.attributes.get();

for (var i in attributes) {
{ attributes[i].setSubmitMode(never); }
}

 

The problem was when looping round the variables in attributes it was also returning functions, which caused a crash.

I fixed the code by doing this

for (var i in attributes) {

{
i f (isNa!N(i)) {
attributes [i]setSubmitMod.e(“never”);
}
}
}

 

 

Not Quite Right

Something was bugging me about the code.  If that problem was a problem whcommon y had I never seen that code before?

Why had I never seen this error before?

I mentioned the problem and solution to another developer and he instantly said

 

The code must have been using the bad for loop

What!, no one told me there was a bad for loop in Javascript, why has no one told me about the bad for loop, come on people.

 

The Good, the bad and the ugly of For statements

 

The Bad – For In Loop for Array Iteration

I searched the internet and found this forum discussion with a great explanation

http://stackoverflow.com/questions/5263847/javascript-loops-for-in-vs-for

I am copying the top answer because it’s awesome

 

Don’t use for..in for Array iteration.

It’s important to understand that Javascript Array’s square bracket syntax ([]) for accessing indicies is actually inherited from the Object

obj.prop === obj['prop']  // true

The for..in structure does not work like a more traditional for..each/in that would be found in other languages (php, python, etc…).

Javascript’s for..in is designed to iterate over the properties of an object. Producing the key of each property. Using this key combined with the Object‘s bracket syntax, you can easily access the values you are after.

var obj = {
    foo: "bar",
    fizz: "buzz",
    moo: "muck"};


for ( var prop in obj)  {
    console.log(prop);      // foo / fizz / moo
    console.log(obj[prop]); // bar / buzz / muck}

And because the Array is simply an Object with sequential numeric property names (indexes) the for..in works in a similar way, producing the numeric indicies just as it produces the property names above.

An important characteristic of the for..in structure is that it continues to search for enumerable properties up the prototype chain. It will also iterate inherited enumerable properties. It is up to you to verify that the current property exists directly on the local object and not the prototype it is attached to with hasOwnProperty()

for ( var prop in obj)  {
    if ( obj.hasOwnProperty(prop) ) {
        // prop is actually obj's property (not inherited)
    }
}

(More on Prototypal Inheritance)

The problem with using the for..in structure on the Array type is that there is no garauntee as to what order the properties are produced… and generally speaking that is a farily important feature in processing an array.

Another problem is that it usually slower than a standard for implementation.

Bottom Line

Using a for...in to iterate arrays is like using the butt of a screw driver to drive a nail… why wouldn’t you just use a hammer (for)?

 

Hosk Interpretation

The important point here is ForIn statements in javascript return user defined properties as well as numeric indexes.  EEK this explains why I was getting “IndexOf” in my for loop.

It also suggests the index numbers are not gauranteed to come out in a sequential order.  This might not be a problem because all the numbers will come out but if you were expecting them in order the for…in could sneak in a very odd bug to find.

Performance is also slow using the forin loop (although in this case it wasn’t really a problem/consideration), this forum discussion also discusses more about performance of for loops if you are interested in finding out more

http://stackoverflow.com/questions/13645890/javascript-for-in-vs-for-loop-performance

 

The Good

So what For loop should you use in your Javascript for iterating arrays.

When I stepped through this for statement the “IndexOf” value wasn’t returned

var attributes = Xrm. Page. data. entity. attributes. get ();

for ( var i = 0; i < attributes. length; i++) {

attributes[i]. setSubmitMode("never"); }


The Bad

The bad was the original bug someone put in there, it’s the wrong, evil for loop, didn’t the developer know anything!  Well technically I didn’t know about the bad for loop until today.

for (var i in attributes) {
{ attributes[i].setSubmitMode(never);}} 


 

 

The Ugly

The ugly was my original fix

for (var i in attributes) {
    if(!isNaN(i)) {
    attributes [i]setSubmitMod.e(never);}}
    


 

It worked but it wasn’t quite right, it was working around the problem of using the wrong for loop.  It took longer because it was returning functions as well as numbers.

 

what have I learnt

I have learnt there are good and bad for loops in Javascript, yes, I went back and changed the code to use the correct for loop.

I  learned it’s good to discuss things with your fellow developers because you might teach them something new or they might teach you a new trick or way to do something.

 

It’s good to talk

It’s good to talk/blog about quirks and problems you experience programming.  Often developers build up areas of expertease which is usually based around the experience they have gained from projects they have worked on.

 

Be willing to learn

I believe in continuous improvement, always striving to learn and improve.  Every mistake/bad coding practice you can get rid off will be replaced by good code.

More good code == better developer

 

Don’t base your knowledge just on experience

Good developers learn the best practices through their own ideas/experience, reading articles/books on programming.

Good developers are always trying new technology/releases, not only does this get them ready for the new functionality but it gives them ideas

On a related subject is my blog on why you should read the what’s new for CRM 2015, it’s all about learning baby!

CRM 2015 SDK – Why you should read the What’s new for developers

 

I believe CRM certifications (customization and extending) are good ways to learn the new functionality in CRM 2013 and broaden your CRM development knowledge.  I  read and used parts of CRM I hadn’t used in any projects I had worked on but which came up in future projects.

My point is you can learn areas of coding/CRM you haven’t used in a project by reading and trying the functionality yourself.  When the time comes to use it in a project you already have a good idea (and maybe a bit of experience) of how to use it, which means your learning curve on new functionality will be shorter than someone with no knowledge of it.

With CRM 2013 it’s easy, you can easily create a CRM 2013 on line trial to try out all the new functionality, you have no excuse because I have created a blog on how to get a CRM 2013 up and running

Step by Step guide to creating a CRM 2013 Online trial

 

Times change but standards must remain

and if the Hosk catches you writing poor code, I will send round the heavy mob

CRM 2013 – Using Dynamic Javascript

Javascript is a slippery beast, Slave to no one and master to many.   It’s just a quick blog post today, not as quick as this article I found written by me

CRM 2011 – Javascript snippet – How to remove all existing values from an OptionSet

 

I’m more happy in the .net and C# world with it’s static variables.

What I mean by this is C# you have to declare the variable you are going to use e.g.

  • string
  • int
  • bool
  • custom type

 

but with Javascript a var can be anything, it’s like something out of X-men changing and morphing it’s way along.

Here is a good article about static and dynamic languages

Static vs. dynamic typing of programming languages

 

Why doesn’t Hosk like Dynamic Javascript

Good question, surely I should like dynamic things.

Some of the reasons I don’t like it are

  • Hard to read/understand other peoples code
  • Bugs can be compiled and then appear in runtime when the code is run
  • It encourages the cowboy coders to go to town
  • It’s strange and different

 

Get to the point

I’m not saying I don’t like Javascript it’s just sometimes I want to do things and I’m not sure HOW because the syntax can be a bit crazy.  Like all developers once we have a working example in our hands, we are off.  So recently I saw some interesting Javascript in a project I am working and I was intrigued to understand how it worked and use it again.

One cool feature about Javascript is the ability to pass in function names using variables, a bit like reflection(ish), but only once you know how because I tried searching for this on the internet and fell down a big dark hole.

 

Example

On a form I have 4 OptionSets which we are dynamically setting the values to.

If I pass in the OptionSetField name I can dynamically get the control


var control = Xrm .Page .getControl (OptionSetFieldName);

I can then clear this control


control. clearOptions();

I can then add in the new values and build it up.  The beauty of dynamic code is I can use the same code for all the OptionSets because I can pass in the name of the control.

When adding a the new optionSet values in, I can use a dynamic variable to retrieve the field name from array, which contains values retrieved from a fetchXML query.  The childField is the name of the field in CRM.


      var option = {
                    value: retrievedOptionSet[i]. text == "" ? "null" : retrievedOptionSet[0].attributes [childField]. value,
                    text: retrievedOptionSet[0].attributes [childField]. formattedValue
                };
                control. addOption(option);
            }


Summary

It may be common knowledge to all you JavaScript wizards out there, but I hadn’t used or seen JavaScript using dynamic names.  It makes sense and it’s very useful so I thought I would share it with you

 

%d bloggers like this: