Monday, January 27, 2014

Why Is CRM Displaying A Section That Has Been Defined As Hidden?

After being head down in CRM for the last 2 years, there are few things that surprise me, but the situation I’m about to describe, threw me for a loop:Huh

Our client had an entity with multiple forms.  All the forms looked virtually identical with the 40 same basic fields, split up among 5 different sections.  4 of the sections were defined as visible, but one wasn’t.  It contained the name of the entity (which was programmatically calculated from various fields, which explains why it was on the form but hidden) along with a couple other fields that were required by the JavaScript of the form, in order to process the business rules of the entity, but the actual business user wouldn’t care about.

Everything had been working fine until we upgraded the on-premise version of CRM from rollup 11 to rollup 15.  After the rollup, we found a bug where on one of the forms, for a particular subset of data, the hidden section was mysteriously being displayed.  I tried everything I could think of, defaulting the section to being hidden, setting it to being hidden as the last function call of the onLoad JavaScript, even setting all of the fields within the hidden section as being hidden.  All to no avail. 

Finally, in a desperate attempt to determine why the section was being displayed, I searched for “setVisible” in the JavaScript of the page, and placed a break point everywhere in the source code.  20 breakpoints later one of the breakpoints was triggered and I finally had a call stack to point me to the problem.  Although it was all minified JavaScript, chopped full of 3 character variables and functions containing only a ‘$’ a letter and a number, one of the function’s names was in English and caught my eye, “setFocus”.  Why was Microsoft setting the focus on a random field on my custom form?  A few debugging steps later, and I had my answer:

CRM has JavaScript that runs after the onLoad function of the form to find the first field on the form that is not read-only, and then sets the focus on that field.  As a part of the setFocus function, it ensures the field is visible by not only setting the field as visible, but setting it’s parent section as visible as well.  So what was happening on this one particular form was all of the fields on the form before the hidden section had been marked as read-only, and when Microsoft’s JavaScript searched for the first field that was not read-only, it found the name field in the hidden section, set the focus on it, which made the section visible.

The solution was relatively simple, make all the fields in the section read-only, and update any JavaScript that updated them to always force submit.  Making the fields read-only removed them from being valid focusable candidates, and adding force submit to each field ensured that any updates the JavaScript made would still get posted back and updated in CRM.  Problem Solved.

Debugging Microsoft’s minified JavaScript is never fun or easy, but sometimes it’s a necessity.  Happy debugging!

No comments: