Do you need the value from a related entity, like a lookup? I had written this for CRM 4 a while back, and people use it, but I occasionally get questions about looking up other values in CRM. This bit of code will help you find those values on a related object. Below are two options to do this. Option 1: using the REST SDK and JSON2, and then Option 2: using Jaimie Ji’s XRM Service Toolkit.
Jaimie Ji’s XRM Service Toolkit provides a comprehensive set of JScript libraries for interacting with the SOAP and REST SDK through JavaScript. While Option 1 in this particular use case is fairly simple, when you start needing to do more advanced things, you may want to look at using that kit. It is fairly comprehensive and he keeps it up to date.
Option 1: Using the REST SDK and JSON2
Using the REST SDK is great, and there are some really good examples in the CRM SDK help file. Now in order to use the below code-block, you need to use JSON.
JSON, or JavaScript Object Notation, is a text format that is used to interchange data. JSON2.js is a lightweight javascript that convert the strings to javascript objects and vice-versa. The CRM REST SDK can return data in JSON format.
To get the code for JSON2, you can go here. You will need to embed this code into your javascript file or include json2.js along with the code below. Without it, you will not be able to parse the data properly, and the code below uses the JSON library in json2.js.
Ok, below we have 3 functions:
- getServerUrl : which gets the server URL – taken from the CrmRestKit
- Lookup_Changed : what you call when a lookup is changed
- retrieveReqCallBack : the callback function that performs any actions
You would put Lookup_Changed in the change event of a lookup field and specify the attributes like one of the following:
- ‘contactid’,'Contact’,'contactlookup’
- ‘contactid’,'Contact’,'contactlookup’,['Telephone1']
- ‘contactid’,'Contact’,'contactlookup’,['Telephone1','FullName]
Then you’d put your actions inside the retrieveReqCallBack.
function getServerUrl() {
// From CrmRestKit.js
var localServerUrl = window.location.protocol + "/" + window.location.host;
var context = parent.Xrm.Page.context;
if (context.isOutlookClient() && !context.isOutlookOnline()) {
return localServerUrl;
}
else {
var crmServerUrl = context.getServerUrl();
crmServerUrl = crmServerUrl.replace(/^(http|https):\/\/([_a-zA-Z0-9\-\.]+)(:([0-9]{1,5}))?/, localServerUrl);
crmServerUrl = crmServerUrl.replace(/\/$/, "");
}
return crmServerUrl;
}
function Lookup_Changed(attributeName, entityName, callbackId, columns) {
var serverUrl = Xrm.Page.context.getServerUrl();
var ODataPath = serverUrl + "/XRMServices/2011/OrganizationData.svc";
var lookup = Xrm.Page.data.entity.attributes.get(attributeName).getValue();
if (lookup===null) {
return false;
}
var id = lookup[0].id;
if (id == null) {
return false;
}
var retrieveReq = new XMLHttpRequest();
var url = ODataPath + "/"+entityName+"Set(guid'" + id + "')";
if (columns !== undefined && columns !== null) {
url = url + "?$select=" + columns.join(',');
}
retrieveReq.open("GET", url, true);
retrieveReq.setRequestHeader("Accept", "application/json");
retrieveReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
retrieveReq.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
if (this.status == 200) {
var data;
var jData;
jData = JSON.parse(this.responseText);
if (jData && jData.d && jData.d.results && jData.d.results.length > 0) {
data = jData.d.results[0];
} else if (jData && jData.d) {
data = jData.d;
}
if (data == null) {
return;
}
retrieveReqCallBack(callbackId, data);
}
}
};
retrieveReq.send();
return true;
}
function retrieveReqCallBack(calltype, data) {
var toLookup=function(data) {
if (data==null || data=="" || (data.Id==null)) {
return null;
}
var result=new Array();
result[0] = {};
result[0].id = data.Id;
result[0].name = data.Name;
result[0].entityType = data.LogicalName;
return result;
}
switch (calltype) {
case 'pricelookup':
Xrm.Page.data.entity.attributes.get("new_pricecategorylookup").setValue(toLookup(data.new_pricecategorylookup);
break;
case 'contactlookup':
Xrm.Page.data.entity.attributes.get("insp_poctelephonenumber").setValue(data.Telephone1);
break;
default:
break;
}
}
Option 2: Using the XrmServiceToolkit with similar functions
Ok, now let’s assume you are using the XRM Service Toolkit, and you want to do the same thing, using a Lookup_Changed function and the retrieveReqCallBack function. Instead of embedding JSON and a method to get the server url, you can use the following:
function Lookup_Changed(attributeName, entityName, callbackId, columns) {
var lookup = Xrm.Page.data.entity.attributes.get(attributeName).getValue();
if (lookup===null) {
return false;
}
if (lookup[0].id == null) {
return false;
}
XrmServiceToolkit.Rest.Retrieve(
lookup[0].id,
entityName,
columns,
null,
function (result) {
retrieveReqCallBack(callbackId, result);
},
function (error) {
throw error;
},
true
);
}
function retrieveReqCallBack(calltype, data) {
var toLookup=function(data) {
if (data==null || data=="" || (data.Id==null)) {
return null;
}
var result=new Array();
result[0] = {};
result[0].id = data.Id;
result[0].name = data.Name;
result[0].entityType = data.LogicalName;
return result;
}
switch (calltype) {
case 'pricelookup':
Xrm.Page.data.entity.attributes.get("new_pricecategorylookup").setValue(toLookup(data.new_pricecategorylookup);
break;
case 'contactlookup':
Xrm.Page.data.entity.attributes.get("insp_poctelephonenumber").setValue(data.Telephone1);
break;
default:
break;
}
}
The XRM Service Toolkit does a lot, and I would suggest checking it out.

One Response to “Lookup data from a related entity (Lookup) using JScript and the XrmServiceToolkit”