Archive for October, 2013

In my last posts I introduced Composite Controls in Dynamics CRM 2011, and described how JavaScript works with fields inside the controls, including a few limitations. In this post I wanted to see how we can use Business Rules on fields in the fly-out menu. I will put to test all 5 ‘actions’ we can perform with Business Rules, and see if the results are any different to JavaScript.

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

Just like with the JavaScript, this sets the value inside the fly-out menu, but doesn’t update the composite field until you click in and out of the field, or save the form. Note: we can also ‘get’ the value of fields in the fly-out menu from Business Rules when setting another field on the form.

3. Set business required using Business Rules

This one works as expected with no issues, same as the JavaScript.

4. Set visibility using Business Rules

We could do this using JavaScript, but it was using an unsupported method. I’m happy to see that this does work with Business Rules. You can see here I have a business rule with no condition (so it always fires) with an action that hides the Address 1: State/Province field. The result is that the field is completely hidden from the fly-out menu.

This works better than the JavaScript approach, and is supported too.

5. Lock or unlock field using Business Rules

This one was not possible using JavaScript, because we couldn’t access the ‘control’. Fortunately we can do this using Business Rules. You can see below the Street 2 field has been locked (disabled) inside the fly-out menu.

It looks like all the Business Rules work just fine with the fields in the fly-out menus, except for maybe the set value issue, which will hopefully be fixed in a future update. Other than that though, this provides us a supported way of hiding fields, and locking/disabling fields in fly-out menus, where it was otherwise not possible or not supported using JavaScript.

Advertisements

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.

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.

In summary, composite controls are pretty cool, and save us a lot of room on the form, especially with the addresses. It would be great if in future using just the UI we could do some of these basic customizations which are so often required in customized solutions, without the need of unsupported JavaScript.

In my next blog posts I’ll be looking at how to get around some of the limitations of composite controls, including what we can do with JavaScript and Business Rules.

In Dynamics CRM 2013, since there is no longer a ‘Workplace’ area in the sitemap by default, we’re now able to define the default pane for users based on their security role. When looking at a user’s personal options, the Default Pane is now set to <Default based on user role>. This can still be changed on a per-user basis, otherwise we can leave it as is and let their security roles decide which pane to show them by default.

How do we customize it? How do we define the default pane in our custom security roles, or even modify the existing security roles? Unfortunately, this functionality is not available to customizers just yet.

Microsoft have commented that yes, this feature is limited right now, and has not been exposed yet; but they have assured us that they are considering it for a future release. Until then, we just have to work with the default roles and default areas which magically work together somehow.

So we can’t customize it (yet), but let’s explore how the default roles work with the default areas for now anyway. Roshan touched on this briefly, but I wanted to drill down and see how it actually works.

Below we can see a table of all the default security roles that ship with CRM. Beside each role we can see which area, if any, they display by default. I was surprised to see that Scheduler and Schedule Manager did not display the Service area.

Role Area
Activity Feeds
CEO-Business Manager
CSR Manager Service
Customer Service Representative Service
Delegate
Marketing Manager Marketing
Marketing Professional Marketing
Sales Manager Sales
Salesperson Sales
Schedule Manager
Scheduler
System Administrator
System Customizer
Vice President of Marketing Marketing
Vice President of Sales Sales

This means that a user assigned the CSR Manager role, for example, will see the Service area by default when loading CRM.

When a user is assigned more than 1 role from different areas, CRM applies a ranking of each role to determine which area to display by default.

The actual ranking looks like this:

1. Vice President of Sales
2. Vice President of Marketing
3. Sales Manager
4. CSR Manager
5. Marketing Manager
6. Salesperson
7. Customer Service Representative
8. Marketing Professional

Basically the highest role you have determines which area you see (Note: this is not actually determined by sitemap order, despite the order being the same as the default sitemap).

For example if a user has the Sales Manager and Marketing Manager roles, they will see Sales by default, as Sales Manager is ranked higher. Even if the user is given Marketing Professional as well, they will still see Sales by default, as Sales Manager is still ranked higher than both other roles.

One more thing to note, is that for now at least, the default areas are coded to their particular roles behind the scenes. So you can change the names of these existing roles, and they will still work with their respective area. However if you ‘copy’ one of these existing roles, or manually create custom roles, they will not work the same. Since a lot of CRM 2011 customers ‘copy’ roles instead of modifying the default roles, this may not function as expected for everyone.

If we are building a highly customized system with all custom security roles and areas, we can also consider modifying the default roles/areas to meet custom requirements if these are otherwise going to be unused. This will allow us to maintain the “hard-coded” default areas associated with the roles to better suit our needs.

Overall, this feature is pretty cool as it means we don’t have to go through and set the default pane manually for each user. Hopefully it’s opened up a bit more in a future release so we can customize this more easily ourselves, without being forced to use the default roles and areas.