Thursday, April 7, 2011

CRM 2011 Javascript - attributes and controls

Based on an optionset (picklist) value I wanted to show or hide a field and make it required or not. Within CRM 4.0 I would write the script by heart. It would look something like this:

//CRM 4.0 Toggle field visible and required
if(crmForm.all.new_picklist.SelectedText == "value-A")
{
    crmForm.SetFieldReqLevel("new_showhidefield", 0);
    crmForm.all.new_showhidefield_c.style.display = 'none';
    crmForm.all.new_showhidefield_d.style.display = 'none';
}
else
{
    crmForm.SetFieldReqLevel("new_showhidefield", 1);
    crmForm.all.new_showhidefield_c.style.display = 'inline';
    crmForm.all.new_showhidefield_d.style.display = 'inline';
}

With the CRM 2011 Xrm.Page model, things have changed quite a lot. The Microsoft Dynamics CRM 2011 SDK describes the Xrm.Page Object Hierarchy. It shows there is a difference between the attributes (Xrm.Page.data.entity.attributes) and the controls (Xrm.Page.ui.controls). Trying to hide or show a field and make it required/not required made me realize that depending on functional requirements you have to figure out if you need to work with the attribute or the control (or both).

For example:
For making a field required, you need to work with the attribute
For making a field hidden, you need to work with the control

The SDK describes for both the methods supported:
Xrm.Page.data.entity attribute Methods
Xrm.Page.ui control Methods

So the CRM 2011 javascript for toggling a field visible/not visible and required or not required is this:

toggleLeadVisible = function()
{
    var Leadcontrol = Xrm.Page.ui.controls.get("new_leadid");
    var Leadattribute = Xrm.Page.data.entity.attributes.get("new_leadid");

    if(Xrm.Page.getAttribute("new_customertype").getText() == "Lead")
    {
        Leadcontrol.setVisible(true);
        Leadattribute.setRequiredLevel("required");
    }
    else
    {
        Leadcontrol.setVisible(false);
        Leadattribute.setRequiredLevel("none");
    }
}

It’s quite simple. Just know what you can do with attributes and what with controls!

Friday, February 25, 2011

Using generic functions – fieldnames- in CRM 2011

With the new webresources structure in Microsoft Dynamics CRM 2011, it has become a lot easier, or at least a lot more self evident, to use generic javascript functions instead of hard-coded scripts. Off course with CRM 3.0 and 4.0 one could write generic functions and call those functions when needed. But reality is that in a lot of situations fieldnames were hardcoded in the javascript.

For example, to add the value of Field A to Field B and set the result in Field C, both the onchange of Field A and Field B would contain the following javascript:

crmForm.all.new_fieldc.DataValue = crmForm.all.new_fielda.DataValue + crmForm.all.new_fieldb.DataValue;

With CRM 2011 it is not possible write the javascript directly on the onchange of the field, but you will have to call a function from a webresource.

Now let’s assume that you have an entity with 3 sets of 3 fields (2 source fields and 1 result field) on the form and you want to populate the 3 result fields with the result outcome of field 1 plus field 2. If you follow on the CRM 4.0 structure, the result would be a webresource with 3 similar javascript functions containing the fieldnames and the onchange events of the 6 source fields calling 1 of those 3 functions.

So how to do this in a CRM 2011 way using the ‘pass parameters to the function’? Start with creating a new javascript webresource and give it a name, in this example called ‘new_testscripts’. In this webresource, write a javascript function that contains 3 parameters. In this example is the function name ‘calcAddValues’ and the parameter names ‘sResultField’, ‘sFieldA’ and ‘sFieldB’, that represent the fieldnames to be used and write the logic as you would with hardcoded fieldnames like this:

function calcAddValues(sResultField,sFieldA,sFieldB)
{
if((Xrm.Page.getAttribute(sFieldA).getValue() != null)||(Xrm.Page.getAttribute(sFieldB).getValue() != null))
{
Xrm.Page.getAttribute(sResultField).setValue(Xrm.Page.getAttribute(sFieldA).getValue() + Xrm.Page.getAttribute(sFieldB).getValue());
}
else
{
Xrm.Page.getAttribute(sResultField).setValue(null);
}
}

Save and publish the webresource. Now you can use this function on any CRM form and call it as many times as you like. To do so, first add the webresource as a library to the form. When included, go to the properties of a field and set the OnChange event by selecting the library, set the name of the function and add the fieldnames to be used in the function as a comma separated list of parameters that will be passed to the function.

Here’s an example on how to do so:

Jscript_Parameters

Advantages

Using the new Microsoft Dynamics CRM 2011 structure creates the possibility to write generic javascript functions and have them collected in one place. Calling a function is easy, just using the function name and providing some parameters when necessary will suffice. No duplicated code is required. Maintenance and future adjustments will be a lot easier. Fixing one piece of javascript code will result in a change for every instance where the code is called.

The catch: make sure that if you change an existing function for one specific requirement that there’s no other part within your Microsoft Dynamics CRM solution that breaks.