Dynamics CRM in the Field

Information from the Microsoft Dynamics CRM PFE team working in the field

Showing related information in a CRM 2011 form

Showing related information in a CRM 2011 form

Rate This
  • Comments 21

With CRM 2011 on the verge of being released there are new features being introduced that will allow you to show  1:N related records in a Sub Grid but there is still a limitation of showing information that is from a N:1 (lookup) relationship. 

Using some other new features of CRM 2011 I have created a Web Resource that will allow you to show related information from a lookup field. 

This Web Resource is a custom html page that pulls information from a specified lookup and queries CRM using the new REST endpoint  for the related data, and displays it in a simple format.

Here is what it looks like loaded into the form.  This example shows information being pulled for the Primary Contact on the Account form.

 

image

 

The Web Resource pulls the GUID and Record Type from the Primary Contact Field-- and using the Field parameters specified on the Web Resource--queries for the contact information and displays it inline.

 

Here is how to set it up. 

 

1. Download the Solution file ***HERE***

2. Import the Solution File.  After the import you should have a new solution  called “Related Information”

                  image

3. Open the Solution to verify you have 3 new Web Resources.

                   image

4. Open up the entity form that you want to add the Web Resource to.  Example: Account Form (Tip: You can now open an entity record, click the “customize” tab at the top and then click the “Form” button to open up the designer)

5. Either highlight an existing section or create a new section to add your Web Resource to.

6. Once a section is highlighted, click the “Insert” tab at the top and then click the “Web Resource” button on the ribbon.

        imageimage

7. In the Web Resource field, select the related.html WR that was added.

8. Enter a name into the “Name” and “Label” field.

9. Enter the parameter string in the “Custom Parameter(data)” field.

  Parameters

  • lookup – The lookup column name that you want to show related information from.  Example: primarycontactid
  • fields – Comma delimited string of columns you want to pull from the related entity. Uses Schema Name
  • labels – The labels you want to display for each field. Has to be in the same order as the field list.

Example: lookup=primarycontactid&fields=FirstName,LastName,Telephone1,EMailAddress1&labels=First Name,Last Name,Business Phone,Email Address

                   image

10. Click Ok

11. Save the Form

12. Publish Customizations and test your form

 

Enjoy!

 

You can find more information regarding related services we provide here.

Development Workshop

Code Review

 

 

This customization is provided as-is.

  • When I try to import the solution, I get an error that I am missing:

         new_/Scripts/FormatPhoneNumber.js

    I am using a fresh trial tenent from Microsoft's online offering (using 2011)

  • I apologize, it looks like there was something that was left in the solution.   There is a custom function that was added to the phone number field on the Contact.   You can either remove it or wait for me to upload an updated solution file.

  • Hello there- did you ever get to replace the solution?

  • Same issue here - On import, FormatPhoneNumber.js missing in Account form.  Would love to use this, but can't get it imported.  Thanks.

  • Hi, I also cant import it into a CRM standard setup on-premise. In order for anyone to use this solution you'll probably need to remove the reference to FormatPhoneNUmber.js or simply include that into the solution.

    Thank you

  • Custom Entity Solution:

    If you haven't noticed, this code only works with Standard Entities in CRM.  The reason is in side the retrieveRecord(ID) function.  The command "retrieveReq.open("GET", ODataPath + "/" + entityName.toTitleCase() + "Set(guid'" + Id + "')", true);" set's the Entity Name to Title Case (.toTitleCase()).  Custom Enitites are new_custom_entity (all lower cases).

    I have modified the Web Resource code to accept an optional parameter entityName to handle custom entities. If you want to retrieve fields from the custom entity, add entityName=[new_custom_entity] to the parameter.

    If you leave out the entityName, the code will still work as originally written. (note: I have made some formatting adjustments that is different from the orginal code)

    Hope this helps someone.

    (I had problems posting the code, so I will try to add the code in the next post...)

  • Post this code between <SCRIPT>  </SCRIPT>

    ------ START CODE: -----

       var FORM_TYPE_UPDATE = 2;

       var FORM_TYPE_READ_ONLY = 3;

       var FORM_TYPE_DISABLED = 4;

       var ODataPath;

       var serverUrl;

       var entityName = "";

       var id = "";

       var fields;

       var labels;

       var lookup;

       var rows = 2;

       var entity;

       var html = "<table cellpadding='1' cellspacing='0' height='1%' style='table-layout: fixed;' valign='top' width='100%'>";

       html += "<col width='115'><col><col class='FormSection_WriteColumnHeaders_col' width='135'><col>";

       function onload() {

           init();

       }

       function init() {

           serverUrl = Xrm.Page.context.getServerUrl();

           ODataPath = serverUrl + "/XRMServices/2011/OrganizationData.svc";

           GetParameters();

           if (parent.Xrm.Page.ui.getFormType() == FORM_TYPE_UPDATE ||

               parent.Xrm.Page.ui.getFormType() == FORM_TYPE_READ_ONLY ||

               parent.Xrm.Page.ui.getFormType() == FORM_TYPE_DISABLED) {

               var value = parent.Xrm.Page.ui.controls.get(lookup).getAttribute().getValue();

               if (value != null) {

                   id = value[0].id.replace('{', '').replace('}', '');

                   // Check to see if entityName Parameter was supplied: if not then get it from the lookup control

                   if (entityName==""){

                       entityName = value[0].entityType.toTitleCase();

                   }

               }

           }

           retrieveRecord(id);

       }

       function LoadTable() {

           var index = 1;

           for (var i = 0; i < fields.length; i++) {

               if (index == 1)

                   html += "<tr valign='top'>";

               html += "<td class='ms-crm-Field-Normal'><label><b>";

               if (labels != null)

                   html += labels[i];

               else

                   html += fields[i];

               var val = "";

               try {

                   val = entity[fields[i]];

               }

               catch (err) { }

               html += "</b></label></td><td align=left>" + val + "</td>";

               if (fields.length == 1)

                   html += "<td class='ms-crm-Field-Normal' colspan=2> 4</td>";

               if (index == rows) {

                   html += "</tr>";

                   index = 1;

               }

               else

                   index++;

           }

           html += "</table>";

           related.innerHTML = html;

       }

       function retrieveRecord(Id) {

           var retrieveReq = new XMLHttpRequest();

           // Removed the .toTitleCase() command to support Custom Enitities

           retrieveReq.open("GET", ODataPath + "/" + entityName + "Set(guid'" + Id + "')", true);

           retrieveReq.setRequestHeader("Accept", "application/json");

           retrieveReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");

           retrieveReq.onreadystatechange = function () {

               retrieveReqCallBack(this);

           };

           retrieveReq.send();

       }

       function retrieveReqCallBack(retrieveReq) {

           if (retrieveReq.readyState == 4 /* complete */) {

               if (retrieveReq.status == 200) {

                   //Success

                   entity = JSON.parse(retrieveReq.responseText).d;

                   LoadTable();

               }

               else {

                   throw new Error("Error retrieving Record");

               }

           }

       }

       function GetParameters() {

           var querystring = unescape(window.location.search.replace('?', '').replace('data=', ''));

           var params = querystring.split('&');

           for (var i = 0; i < params.length; i++) {

               var param = params[i].split('=');

               switch (param[0]) {

                   case "entityName":

                       // New entityName Parameter to support custom entitites

                       // for custom entities; add entityName=new_[name] (all lower case)

                       entityName = param[1];

                       break;

                   case "lookup":

                       lookup = param[1];

                       break;

                   case "fields":

                       fields = param[1].split(',');

                       break;

                   case "labels":

                       labels = param[1].split(',');

                       break;

               }

           }

       }

       String.prototype.toTitleCase = function () {

           var A = this.split(' '), B = [];

           for (var i = 0; A[i] !== undefined; i++) {

               B[B.length] = A[i].substr(0, 1).toUpperCase() + A[i].substr(1);

           }

           return B.join(' ');

       }

    --------- END CODE

  • The solution has been updated to remove the FormatPhone reference.

  • Doesn't seem to work here; I've added the resource to a custom entity (slfn_reservation) to get information about a related Unit (slfn_unit).

    lookup=slfn_unitid&fields=slfn_Advance_Amount,slfn_Description&labels=Advance,Description&entityName=slfn_unit

  • The function "ToTitleCase" doesn't work for custom entities since the REST service URL is case sensitive.   The OOB entities will be title case and the custom entities will be lower.   You will need to refactor it to account for that.

  • This woks great! The only thing is that it doesn't print. Is there any way to make it show up in the print preview? We just get an empty box.

    Thanks!!

  • Hi there, this is a wonderful solution and it works well for me. The only problem is when one field has no information, I get some words that say NULL. Do you know how to fix it?

  • @Jonathan,

    I would look at your field names and make sure they're correct.  When I have issues with these sorts of things I almost always start by pressing F12 in IE and starting to debug (it's a fantastic script debugger).  That should guide you down the right path to the problem.  

    I hope that helps!

    Sean McNellis

    Premier Field Engineer

  • Hi-

    When I try using this web resource, the web resource that is displayed is blank...

    imgur.com/8XDPo3r,XgRgiaC

    imgur.com/8XDPo3r,XgRgiaC

    any help would be great..

    thanks,

    J Stone

  • I have been trying for two days, but I can't seem to get this to work.  Any help would be greatly appreciated.

    Details

    ----------

    Two custom entities:

     1. Client Info (schema name:  cpdc_clientinfo)

     2. Matter (schema name: cpdc_matter)

    > Client Info record can have multiple Matters associated with it.

    > When displaying a matter, The Client Info picker displays the client NUMBER, but not the name.  Trying to use this solution to display that client name on the matter form without duplicating the data.

    Implementation

    ------------------------

    My WR Properties:   lookup=cpdc_clientnumberid&entityName=cpdc_clientinfo&fields=cpdc_clientname&labels=Client Name

    > cpdc_clientnumberid - name of the fild on the matter form that is the picker for the related Client Info entity

    > cpdc_clientinfo - name of the custom entity I'm trying to retrieve per previous blog comment above.

    > cpdc_clientname - name of the field from the custom entity I'm trying to retrieve and display.

    When I pull up the matter form, the WR field that should display the client name is just a div with blue background.  NO DATA.

    When I debug, It throws an error as indicated below.  Seemingly showing that retrieveReq.status IS NOT equal to 200.

       function retrieveReqCallBack(retrieveReq) {

           if (retrieveReq.readyState == 4 /* complete */) {

               if (retrieveReq.status == 200) {

                   //Success

                   entity = JSON.parse(retrieveReq.responseText).d;

                   LoadTable();

               }

               else {

    -->                throw new Error("Error retrieving Record");

               }

           }

       }

    I am in desperate need of getting this to work.  ANY HELP WOULD BE GREATLY APPRECIATED!!

    Thanks,

    Glen

Page 1 of 2 (21 items) 12
Leave a Comment
  • Please add 5 and 7 and type the answer here:
  • Post