JavaScript with Dynamics CRM 2013 Composite Controls

Posted: October 23, 2013 in Dynamics CRM 2013

In my previous post I looked at Composite Controls in Dynamics CRM 2013, and how they combine multiple fields into a single ‘fly-out’ menu. In this post I’m going to explore how the composite controls hold up against JavaScript. Mainly I will be testing the functions commonly used on address fields and name fields, to make sure they can still be used with the composite fields.

1. JavaScript OnChange events on fields in the fly-out menu

Since each individual field inside the fly-out menu is not actually on the form by default, we can’t directly add an event handler to the onchange event of one of these fields. We can however add onchange events to the composite field. In the case of ‘Middle Name’ though, this will not work, as entering a middle name does not update the composite ‘Name’, and so the onchange does not fire.

By adding the event handler to the composite field, it also means the event will fire on any change, and not just when a specific field in the fly-out menu changes.

A better way to handle onchange events on individual fields is to add a hidden section to your form, and add each of the individual address fields into this section. You can then add JavaScript event handlers to the individual fields which will also be applied to the fields in the composite fly-out menu.

As soon as you change the field value in the fly-out, the onchange will fire; even before completing the other fields in the fly-out. You can see here I have a simple function to alert the Country/Region when it changes.

Note: Using .addOnChange() JavaScript does not work. There is no error, but the event is also not fired when changing the value inside the fly-out menu.

2. Getting the value of a field inside the fly-out menu using JavaScript

Now I wanted to try getting the value of a field inside the fly-out menu, where the field is not actually on the form otherwise. Here I am simply alerting the Middle Name of a contact onload:

alert(Xrm.Page.getAttribute("middlename").getValue());

Booya! We can get the field value even though it’s technically not on the form.

3. Setting the value of a field inside the fly-out menu using JavaScript

We can easily ‘get’ the field value, but can we easily ‘set’ the field value? I’ll try a simple setValue() on the Country field to set it to New Zealand by default.

Xrm.Page.getAttribute("address1_country").setValue("New Zealand");

Hmm… not quite right. As you can see above, the composite field is still U.S. but when we click into the field to see the fly-out menu, the country is New Zealand. You can also see in the corner that there are unsaved changes, so CRM has recognised that something has changed.

The composite field won’t be updated until you open the fly-out menu, and then close it again. You can also perform a save (or wait until the auto-save kicks in) and then the composite field will be updated.

We also cannot manually set the value of the composite field (in a supported manor) using JavaScript.

4. Hiding fields in the fly-out menu using JavaScript

Next I wanted to try something a little more complex, hiding one of the fields in the fly-out menu:

Xrm.Page.getControl("middlename").setVisible(false);

No luck here unfortunately. While ‘Xrm.Page.getAttribute’ seems to give us the correct attribute inside the fly-out menu, it looks like ‘Xrm.Page.getControl’ does not give us the control.

Before I give up, I wanted to try some “unsupported” JavaScript as well to see if we can hide it that way:

document.getElementById("fullname_compositionLinkControl_middlename_d").parentElement.style.display = "none";

Hooray! We can hide fields using unsupported JavaScript. However remember that being unsupported, this could break at any time with a future update (or more likely they add support for it).

The element name you need to get includes the composite field name, and the name of the field inside the fly-out menu you’re hiding: “<composite-field-name>_compositionLinkControl_<fly-out-field-name>_d”. For example, to hide the ‘State’ field in the Address 1 block, we would use “address1_composite_compositionLinkControl_address1_stateorprovince_d”.

5. Change Requirement level of fields in fly-out menu using JavaScript

This one is pretty important where we need to conditionally make fields required.

Xrm.Page.getAttribute("firstname").setRequiredLevel("required");

Bingo! First Name is now required.

6. Change the label of fields in the fly-out menu using Javascript

The First Name, Middle Name, and Last Name labels are taken directly off the field name, so you cannot change these on a per-form basis. However, to change the label for all forms, simply change the actual field display name, and the label inside the composite control will be updated.

Here I have customized the Last Name field display name to be ‘Surname’.

The address fields however cannot be changed through the UI. These do not appear to use the field display names, and instead appear to be hard-coded into the composite control. We often localise the address fields for New Zealand addressing, so I didn’t want to give up on this one that easy.

The supported control.setLabel() does not work as we cannot get the control of the field inside the fly-out menu. The last resort was to try “unsupported” JavaScript.

document.getElementById("address1_composite_compositionLinkControl_address1_line1_c").firstChild.firstChild.innerHTML = "Street Address";

Success! The label has been changed inside the fly-out menu. Just like with hiding the fields, we need to specify the address composite field name, as well as the name of the field we’re changing. You can then specify the new label for the field. This approach is unsupported, so use it at your own risk.

It seems that most of the JavaScript functions for the ‘attribute’ works fine, however since we can’t get the ‘control’, we’re not able to easily hide, disable, change labels, or any other functions that require the control without using unsupported code. In my next post I’ll explore Business Rules to see if these can be used with Composite fields, and whether they allow us to do anything that JavaScript can’t.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s