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

10 thoughts on “CRM 2013 – Javascript null setting oddity

  1. ukcrmguru July 15, 2015 / 10:56 am

    You are right, in general, “recommended” level seems pretty useless. If I put a field on a form, I expect you to fill it in, right?

    I tend to suggest using it for fields that are *sometimes* required (by javascript or business rules), as a sort of “pre-warning” to users that although this is not required just now, it might be required later (depending on what else they fill in). So re-setting from required to recommended would make sense here.

    In 2011 days it was especially useful in this scenario if you used right-aligned labels. If you switched from “none” to “required” then the addition of the red asterisk caused the labels to jump to the left to make room. This catches the corner of your eye and is distracting, but not enough to get the user to see what actually changed. Switching from recommended to required and back did not cause this label jump with right-aligned labels.

    Now right-aligned labels don’t exist any more (this property is ignored) so it does not matter.

    In general, in 2013 I would suggest using Business Rules and setting error messages rather than making a field explicitly business required anyway. It helps you to prompt the user more usefully – “This is required because you answered foo to question bar”

    Like

  2. Hosk July 15, 2015 / 11:41 am

    thanks for the comment. I was thinking there might be some legacy reason for adding recommended status level but I couldn’t really think of why.

    I like the idea of error messages to prompt the user. I had forgot the record can’t be saved until the error message is gone
    https://technet.microsoft.com/en-us/library/dn531086.aspx

    Excellent tip, I might add that as a blog post

    Like

  3. anu July 21, 2015 / 9:22 pm

    Hello Hosk,

    How to add a composite address field to custom entity in CRM 2013? Any help would be highly appreciated.

    Like

    • Hosk July 22, 2015 / 11:32 am

      Adam is correct, if you want composite field you need to add a new custom entity and create you composite field by including all the fields needed to create the composite field and then maybe creating one field to link them together.

      Like

      • anu July 22, 2015 / 2:39 pm

        Thank you Hosk

        Like

  4. ukcrmguru July 22, 2015 / 9:02 am

    @anu You can’t reproduce the OOB composite fields with flyouts in any “configuration” way, you can’t simply add a composite field to a custom or OOB entity. You would have to add a bunch of fields, and a longer one to put the concatenated version into and build a custom control to do the work on the form.

    Like

    • anu July 22, 2015 / 2:39 pm

      Thank you

      Like

  5. Andrew Perkin (@PerkintheHermit) February 13, 2017 / 12:04 pm

    What is bonkers is still having to do this in CRM 2016… Thanks for the solution Hosk.. Spent ages working out why setting my lookup to null was failing..

    Like

  6. James Houck May 12, 2017 / 4:19 pm

    Thanks, Hosk. I am having to do some similar scripting to what you described and was just refreshing my memory on the syntax to clear/null a fields when I came across this. I too will have to deal with required fields, so I’m sure this post will have saved me some frustration!

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.