Showing related information in a CRM 2011 form

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.




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”


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


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.


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.


  • 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


10. Click Ok

11. Save the Form

12. Publish Customizations and test your form




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

Development Workshop

Code Review



This customization is provided as-is.

Comments (22)

  1. uiscedan says:

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


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

  2. Daren turner says:

    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.

  3. Ryan says:

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

  4. Jon says:

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

  5. Sharon says:

    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

  6. 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 ""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…)

  7. 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() {



       function init() {

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

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


           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();






       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];


                   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;





           html += "</table>";

           related.innerHTML = html;


       function retrieveRecord(Id) {

           var retrieveReq = new XMLHttpRequest();

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

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

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

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

           retrieveReq.onreadystatechange = function () {





       function retrieveReqCallBack(retrieveReq) {

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

               if (retrieveReq.status == 200) {


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



               else {

                   throw new Error("Error retrieving Record");




       function GetParameters() {

           var querystring = unescape('?', '').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];


                   case "lookup":

                       lookup = param[1];


                   case "fields":

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


                   case "labels":

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





       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

  8. DarenTurner says:

    The solution has been updated to remove the FormatPhone reference.

  9. 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).


  10. DarenTurner says:

    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.

  11. Brian says:

    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.


  12. Jonathan says:

    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?

  13. @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

  14. J Stone says:


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

    any help would be great..


    J Stone

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



    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.



    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) {


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



               else {

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




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



  16. Hi Glen, I'm sorry you're having some issues.  When you debug check out this line of code:

    –"GET", ODataPath + "/" + entityName + "Set(guid'" + Id + "')", true);

    insert a line there like this:

    – alert(ODataPath + "/" + entityName + "Set(guid'" + Id + "')");

    You'll want to make sure you can open this URL in your browser, here is another convention you can use to get the URL:

    – Xrm.Page.context.getServerUrl() +  "/XRMServices/2011/OrganizationData.svc" + "/entityName" + "Set(guid'" + "IDValue" + "')";  

    Notice you'll have to make sure your entity name is correct along with the ID – my guess is that your entity name is either null or cased incorrectly.  You should be able to paste this URL into your browser and get back a record list.  Let me know if you have issues still after looking into this.



  17. Mich says:

    I got most of my fields to show up but one of them is an optionset and I would like the text to show up. I tried optionsetSchemaName.getText() but it's showing as 'undefined'. What am I doing wrong?

  18. Sue says:

    We are using this just to display a single field. If that field contains no data it displays Null.

    Is there a way to hide the blue box area instead?

  19. Gustavo Jimenez says:

    Thanks for this I'm sure it saved us a lot of work.

    I'm already displaying values, but having some issues with dates, for example, instead of showing: 01/03/2011, I'm getting: /Date(1298959200000)/

    Is there any solution for this?


  20. @Mich – check out this article from the SDK:…/hh223541.aspx

    @Sue, yes you can combine this with logic in your iFrame onReadyStateChange javascript event.  Essentially you'll have to pass messages between the iframe and the form so the form can tell if your iFrame is empty – then your iFrame onReadyStateChange code can simply set the visible property to false (using setVisible(false)).

    @Gustavo – see this page in the SDK:…/gg328025.aspx specifically read the "Working with Dates" portion

    Thanks for reading!


  21. Florian Berger says:


    I had these problems too. The problem seems to be that you can't access getFormType() in print preview.

    I changed the init() function in related.htm to check if it's opened in print preview to make it work.

    function init() {        

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

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


               try {

                   if (top.location.href.indexOf("/print/print.aspx") != -1) {

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

                       if (value != null) {

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

                           entityName = value[0].entityType;



                   else 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('}', '');

                           entityName = value[0].entityType;





               catch (err1) {



  22. Deana says:

    I know this blog is a few years old but I would love to use it; however, I’m unable to download the solution which is supposed to be at located here:…i’m receiving the following error Network Error (tcp_error)

    A communication error occurred: “Operation timed out”
    The Web Server may be down, too busy, or experiencing other problems preventing it from responding to requests. You may wish to try again at a later time.

    Please validate that the website address is correct. If problem persists please contact your support team.
    could you perhaps post this solution again? Thank you

Skip to main content