Dynamics CRM 2013 introduces composite fields, which basically combines multiple fields into a single field on a form. This is currently used on ‘Name’ fields to combine first name, middle name, and last name into one ‘Name’ field. It is also used on most address blocks in CRM by combining all the address fields into a single composite field.
As you can see above, we have a single ‘Address 1’ field, which when clicked opens a fly-out menu with our 7 address fields. We can then change the individual values and click ‘Done’, or simply click off the fly-out menu to commit the changes.
The 7 address fields are then combined and formatted nicely into the ‘Address 1’ composite field, so that you can easily see the whole address in 1 field, rather than having to look across 7 different fields. This field can then be added into views and reports, or even exported to excel.
This new composite control is used for most of the main entity address blocks in CRM; including Account, Contact, Lead, Competitor, Quote, Order, and Invoice. It is currently not used on User, Business Unit, and Site. It’s also used on the Name/Full Name fields for Lead and Contact (but not User). Unlike the addresses, the Name composite fields use the existing Name/Full Name field, rather than a new field.
As you can see with the Name field, it uses the Middle Name field in the fly-out menu, but this is not added to the actual ‘Name’. If you wanted to see the person’s middle name, you would need to click into the Name field to open the fly-out menu.
The big question is how customizable is it?
Unfortunately we can’t create our own composite controls. Hopefully this is made possible in a future release, as that would allow for consistency when adding custom entities with address fields etc.
As for customizing the existing composite controls, we also cannot add, remove, or modify fields in the fly-out menus through the UI. This means that for us New Zealanders where we don’t use the ‘State’ address field, we cannot easily remove that from addresses now, or even relabel the fields. Hopefully this is also made editable in the future through the UI.
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.
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.
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:
Booya! We can get the field value even though it’s technically not on the form.
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.
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.
Next I wanted to try something a little more complex, hiding one of the fields in the fly-out menu:
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.
document.getElementById("fullname_compositionLinkControl_middlename_d").parentElement.style.display = "none";
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”.
This one is pretty important where we need to conditionally make fields required.
Bingo! First Name is now required.
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.
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.
1. Show error message using Business Rules
We can add some validation to a field inside the fly-out menu, the red ‘X’ will appear next to the composite field. If we display multiple error messages, for example on Street 1 and 2, only 1 ‘X’ will appear beside the composite field.
2. Set field value using Business Rules
3. Set business required using Business Rules
4. Set visibility using Business Rules
5. Lock or unlock field using Business Rules
P.S. I was going to split this blog post into 3 since it is so long, but given the topic I decided to create a composite blog post with all 3 instead :)