JavaScript in CRM 2011 with the CrmRestKit Used to Query related data on a MS Dynamics CRM form

In this article we discuss how to use javascript in CRM 2011 with the CrmRestKit in order to query related data on a MS Dynamics CRM 2011 Form. Before we begin let’s take a look back…

In a previous article titled Customizing Microsoft CRM to get the Ultimate User Experience (UX), we explained how to use field mappings as a no-code, no JavaScript approach to set related data between entities. This approach, however, isn’t always the best solution. For example, let’s think about a typical process for an Order. On the Order form, we have billing and shipping address information. Using field mappings, we could populate these fields when an order is either converted from and opportunity or created from an account record. But what if the order record is created from scratch? It sure would be nice if the user selected an account from the lookup field on the form, they could immediately see the address information get populated.

This is where we would want to use JavaScript in CRM 2011 to query the related record, in this case the Account entity, and populate the address information. To use JavaScript in CRM 2011 to query data you actually have a couple of options. Here we are going to outline the REST (Representational State Transfer) endpoint that is provided within CRM. Unfortunately using JavaScript in CRM 2011 with REST isn’t as straight forward as one would hope. Microsoft CRM Dynamic does provide some sample code in the SDK to ease this approach, but there are also a number of other, free, libraries that are readily available on the internet. The JavaScript in CRM 2011 library that we will use here is the CrmRestKit available on codeplex (see the full link at the end of the article). Using this library we can easily perform our favorite CRUD (Create, Retrieve, Update, and Delete) operations.

One thing that may be a little confusing is that typically when you interact with form fields through code, you use the lowercase field name. When querying data using REST however, you need to use the mixed case Schema name. So to add some clarity on which name we need to use and where, we will compose a list of the fields that we need on the Order form. We know that we will need the lookup field, for the Account, on the Order form, to trigger our query. So we will first want to take a look at the Order entity and determine what the actual name of the field is. Now one slight caveat is that by default, the Account does not exist directly on the Order form, instead it uses the Customer lookup. The Customer is simply an added layer that supplies a records unique identifier and the type of record (either Account or Contact). To start, we want to locate the Customer field, on the designer of the Order form, and click on Change Properties. On the field properties window, under the Details tab, you will need to make a note of the Name listed. It is case sensitive and should be all lower case.


We then want to repeat this for each of the address fields that we want to populate from the Account entity. For this example we will include, in addition to customerid, the billto_line1, billto_city, billto_stateorprovince, and billto_postalcode field names.

Next we can focus on the data that we will actually be retrieving. Again, since REST uses the Schema Name, we want to use “Account” and not the name “account” which you can see by looking at the listing of entities. Looking at the Field view on the Account entity you can see both the Name and Schema Name listed. Here we can note the Schema Names for the fields that correspond to the Order fields above, including what we will filter on. This list would include AccountId, Address1_Line1, Address1_City, Address1_StateOrProvince, and Address1_PostalCode.

The following table outlines our results:

Order Entity Form (Destination – Name) Account (Source – Schema Name)
customerid AccountId
billto_line1 Address1_Line1
billto_city Address1_City
billto_stateorprovince Address1_StateOrProvince
billto_postalcode Address1_PostalCode

The code we add will be ultimately called in the OnChange event of the Customer lookup field. Before we construct our REST query, we need to retrieve the unique identifier value, which represents the Account, from the Customer field on the form. Since we are dealing with a lookup field, the value from the form is returned as an array of objects. The code to retrieve the unique identifier will look like this:

var selectedAccount = Xrm.Page.getAttribute("customerid");
if (selectedAccount != null) {
   var accountValue = selectedAccount.getValue();
   if ((accountValue != null)) {
       accountId = accountValue[0].id;
   }
}

With the account identifier we can now create the filter for our REST query. To return records from our source. The CrmRestKit provides us a couple of options to do this. If we want to return a single record and we know the identifier of the record, we can use the Retrieve function. If we have one or more results we can use the ByQuery function. Both of these two will work for our scenario, but since we know the identifier of the record we want we will just use the Retrieve function. The Retrieve function takes up to four arguments, the first is the Schema Name of the Entity, and the second is the unique identifier if the record, and the third is an array of Schema Names that we want to retrieve from the entity, and lastly a Boolean to determine if we want synchronous and asynchronous data retrieval. The default value is true (asynchronous) meaning that our page will not wait for the query to finish.

CrmRestKit.Retrieve('Account', accountId, ['Address1_Line1', 'Address1_City', 'Address1_StateOrProvince', 'Address1_PostalCode'])

The same query using the ByQuery function simply specifies the filter in detail.

CrmRestKit.ByQuery("Account", ["Address1_Line1", "Address1_City", "Address1_StateOrProvince", "Address1_PostalCode"], "AccountId eq guid'" + accountId + "'", false)

Now we need to specify what we want to do with the results when they are returned. The CrmRestKit leverages what is known as Promises in our code. This basically means that we have “Promise” to execute an operation. In this case a query to return an Account record. A promise can be either fulfilled or failed. To determine the result of our promise, we evaluate a Then property. In our case we simply pass in a function to loop through the result set. Notice that all we are using to this point is the Schema Names from our source entity.

CrmRestKit.Retrieve('Account', accountId, ['Address1_Line1', 'Address1_City', 'Address1_StateOrProvince', 'Address1_PostalCode']).then(function (data, status, xhr) {
    alert(data.d.Address1_Line1);
    alert(data.d.Address1_City);
    alert(data.d.Address1_StateOrProvince);
    alert(data.d.Address1_PostalCode);
});

Using the ByQuery function would add an additional layer of an array because we could have more than a single result returned.

CrmRestKit.ByQuery("Account", ["Address1_Line1", "Address1_City", "Address1_StateOrProvince", "Address1_PostalCode"], "AccountId eq guid'" + accountId + "'", false).then(function (data, status, xhr) {
   for (var i = 0; i < data.d.results.length; i++) {
       alert(data.d.results[i].Address1_Line1);
       alert(data.d.results[i].Address1_City);
       alert(data.d.results[i].Address1_StateOrProvince);
       alert(data.d.results[i].Address1_PostalCode);
   }
});

The final piece is to set the values of the form fields with the values returned by our query. This is where it is important to understand the distinction between the field names on the Order form and the Schema names returned from the Account query: Xrm.Page.getAttribute([Order Form Field]).setValue([Query Result Field]);

Obviously we will need create a web resource for this script and add a reference to it on the Order form. Before we do, it is important that we include the CrmRestKit and its dependencies to the form in the specific order listed below. Adding these files out of order will cause issues. To do this we will need to download the latest version of these three JavaScript in CRM 2011 libraries. Unless you anticipate making modifications directly to the libraries, we recommend using the compressed or minified version of jQuery for optimization.

  1.  jQuery
  2. JSON2
  3. CrmRestKit

On the Form Designer of the Order entity, we can click on the Form Properties icon in the ribbon control to add the three libraries listed above as well as the web resource that contains our script.

Select the Customer field from the Control drop down list, ensure that the Event is OnChange, and click add to add. Ensure the correct web resource is selected in the Library drop down and add the name of the function that you created.

Publish all of your changes, navigate to your Orders, create a new order and select an Account. You should see the address fields get populated.

You can download the full solution file that includes all of the web resources related to this article and to CRM 2011 Dynamics in the free downloads section.

 Only Members can Access Sample Code! Register in the sidebar for FREE access to sample code and FREE product downloads.

Also, consider using the Script Author tool to further enhance the script by adding a “Ship to same as billing address” checkbox feature.

For additional articles regarding crm 2011 javascript visit our blog and sign up below.

Don’t forget to Register Below to Access FREE Code Samples and Free Product Downloads!
Already registered? Click here to login
Share