In my previous article, I have explained about How to retrieve multiple records using Odata Query in Dynamics 365 Online V 9.X using JavaScript WebAPI?
And now i will use the same example, which i used in my earlier article mentioned in the above link and retrieve multiple Account records using FetchXML query.
Javascript
Multi Option Set / Picklist in CRM 2011 / 13 / 15 using Javascript
Yes it is my 50th Article in WordPress. Hope you all like my articles.
Please provide your valuable comments on my articles to improve further.
Happy New Year to all my blog viewers.
Task: Create a Multi Option Set in contact, for the OptionSet below
Solution: Follow the below steps to select multi Option Set / Picklist values in CRM,
Step 1: Create below fields in Contact form,
Step 2: Place the 2 fields on the required place on contact form, and uncheck Visible by default for “Sport Option Set Values” field.
Step 3: Create Javascript Webresource “new_multiPickList”. Open Text Editor, Copy & Paste the below Code
// Method to convert an optionset to multi select OptionSet
function ConvertToMultiSelect(var_sc_optionset, var_sc_optionsetvalue) {
var optionSetObj = Xrm.Page.getAttribute(var_sc_optionset);
if (optionSetObj != null) {
var options = optionSetObj.getOptions();
if (options != null) {
document.getElementById(var_sc_optionset).style.display = “none”;
// Create a DIV container
var addDiv = document.createElement(“div”);
addDiv.id = var_sc_optionsetvalue + “_m”;
addDiv.style.width = “100%”;
addDiv.style.height = “80px”;
addDiv.style.background = “#ffffff”;
addDiv.style.color = “white”;
addDiv.style.overflow = “auto”;
addDiv.style.border = “1px #6699cc solid”;
document.getElementById(var_sc_optionset).parentNode.appendChild(addDiv);
// Declaration of variables will be used in the loop depending upon the browser
var initialValue = 0,
maxValue = 0,
nAgt = navigator.userAgent;
if (nAgt.indexOf(“Firefox”) != -1) { // If the broswer is “Firefox”
initialValue = 1;
maxValue = options.length;
}
else if (nAgt.indexOf(“Chrome”) != -1 || nAgt.indexOf(“IE”) != -1) { // If the browser is Chrome or IE
initialValue = 0;
maxValue = options.length – 1;
}
else if (nAgt.indexOf(“Safari”) != -1) { // If the browser is “Safari”
initialValue = 1;
maxValue = options.length;
}
// Initialize checkbox controls
for (var i = initialValue; i < maxValue; i++) {
var pOption = options[i];
if (!IsChecked(pOption.value, var_sc_optionsetvalue)) {
var addInput = document.createElement(“input”);
addInput.type = “checkbox”;
addInput.style.border = “none”;
addInput.style.width = “25px”;
addInput.style.align = “left”;
addInput.style.color = “#000000”;
addInput.onclick = function() {
OnSave(var_sc_optionset, var_sc_optionsetvalue);
createTable(var_sc_optionsetvalue);
}
} else {
var addInput = document.createElement(“input”);
addInput.type = “checkbox”;
addInput.checked = true;
addInput.setAttribute(“checked”, true);
addInput.checked = “checked”;
addInput.defaultChecked = true;
addInput.style.border = “none”;
addInput.style.width = “25px”;
addInput.style.align = “left”;
addInput.style.color = “#000000”;
addInput.onclick = function() {
OnSave(var_sc_optionset, var_sc_optionsetvalue);
createTable(var_sc_optionsetvalue);
}
}
//Create Label
var addLabel = document.createElement(“label”);
addLabel.style.color = “#000000”;
addLabel.innerHTML = pOption.text;
var addBr = document.createElement(“br”); // it’s a ‘br’ flag
document.getElementById(var_sc_optionset).nextSibling.appendChild(addInput);
document.getElementById(var_sc_optionset).nextSibling.appendChild(addLabel);
document.getElementById(var_sc_optionset).nextSibling.appendChild(addBr);
}
}
}
}
// Check if it is selected function IsChecked(pText, optionSetValue) {
var selectedValue = Xrm.Page.getAttribute(optionSetValue).getValue();
if (selectedValue != “” && selectedValue != null) {
var OSVT = selectedValue.split(“,”);
for (var i = 0; i < OSVT.length; i++) {
if (OSVT[i] == pText)
return true;
}
}
return false;
}
// var_sc_optionsetvalue >> Provide logical-name for field which will
// store the multi selected values for Option Set
// optionSet>> Provide logical-name of Option Set field
function OnSave(optionSet, var_sc_optionsetvalue) {
var OS = document.getElementById(optionSet),
options = Xrm.Page.getAttribute(optionSet).getOptions(),
getInput = OS.nextSibling.getElementsByTagName(“input”),
result = “”,
result1 = “”;
var nAgt = navigator.userAgent;
for (var i = 0; i < getInput.length; i++) {
if (getInput[i].checked) {
result += getInput[i].nextSibling.innerHTML + “,”;
if (nAgt.indexOf(“Firefox”) != -1) { //If the broswer is “Firefox”
result1 += options[i + 1].value + “,”;
}
else if (nAgt.indexOf(“Chrome”) != -1 || nAgt.indexOf(“IE”) != -1) { //If the browser is Chrome or IE
result1 += options[i].value + “,”;
}
else if (nAgt.indexOf(“Safari”) != -1) { //If the browser is “Safari”
result1 += options[i + 1].value + “,”;
}
}
}
//save value
Xrm.Page.getAttribute(var_sc_optionsetvalue).setValue(result1);
}
// var_sc_optionsetvalue >> Provide logical-name for field which will
// store the multi selected values for Option Set
function createTable(var_sc_optionsetvalue) { // Get OptionSet value
var OptionValue = Xrm.Page.getAttribute(var_sc_optionsetvalue),
c_OptionValue = Xrm.Page.getControl(var_sc_optionsetvalue),
d_OptionValue = var_sc_optionsetvalue + “_d”;
if (OptionValue.getValue() != null) {
var OptionValueHtml = “<div style=\”overflow-y:auto;width:100%;display: none; min-height: 5em; max-height: 1000px;\”>”,
OptionValueHtml += “<table style=’width:100%;height: 100%;’>”,
OptionValueV = OptionValue.getValue(),
OptionValueT = OptionValueV.split(“,”),
cols = 0;
for (var row = 0; row < OptionValueT.length – 1; row++) {
OptionValueHtml += “<tr style=’height:20px;’>”;
for (var i = cols; i < cols + 3; i++) {
OptionValueHtml += “<td style=’width:33%;’>”;
if (OptionValueT[i] != null || OptionValueT[i] != undefined) {
OptionValueHtml += OptionValueT[i];
}
OptionValueHtml += “</td>”;
}
cols = cols + 3;
OptionValueHtml += “</tr>”;
if (cols >= OptionValueT.length) {
break;
}
}
OptionValueHtml += “</table>”;
OptionValueHtml += “</div>”;
document.getElementById(d_OptionValue).innerHTML = OptionValueHtml;
}
}
Step 4: Open Contact Form -> Form Properties.
Add the webresource “new_multiPickList” on Contact Form.
Select Library “new_multiPickList” and provide the function name “ConvertToMultiSelect” on “OnLoad” Event.
Provide the parameters “new_favouritesport“, “new_sportoptionsetsvalues“.
Step 5: Select Library “new_multiPickList” and provide the function name “OnSave” on OnSave Event.
Provide the parameters “new_favouritesport“, “new_sportoptionsetsvalues“.
Step 6: Save & Publish Contact Form. Open any CRM record to see the below Output,
Sources:
http://slalomdotcom.wordpress.com/2011/05/23/multi-select-option-sets-in-dynamics-crm/
http://mscrmmindfire.wordpress.com/2014/01/30/crm-2013-multi-pick-list-2/
Jsbeautifier Online JavaScript / HTML Formatter
When we are working with CRM, we often work on JavaScript or HTML.
For this we generally use Visual Studio for formatting. But, we have So many Online editors / formatters available.
In Online editors, I feel comfortable working with http://jsbeautifier.org/ (Open Source)
Want to give a try, check website.
Please comment on this article.
Hope you like it 🙂
HTML Webresource example in CRM 2011/13/15
Follow the simple example to create HTML webresource in CRM form.
Task: Create a HTML webresource, to show list of Security Roles associated to User in User (systemuser) record
Solution: Follow the below steps,
Step 1: Should include Jquery webresource in the HTML Page. Download the latest CRM SDK &Goto the below path,
SDK\SampleCode\JS\RESTEndpoint\JQueryRESTDataOperations\JQueryRESTDataOperations\Scripts
Step 2: Browse for jquery_1.9.1.min and Create “new_ jquery_1.9.1.min” Jscript Webresource as shown below,
Step 3: Create HTML Webresource “new_userRolesHTML”,
Step 4: Click on Text Editor, Copy & Paste the below code, or Click here to get HTML code
<html> <head> <title>User Security Roles</title> </head> <body> <script src="ClientGlobalContext.js.aspx" type="text/javascript"></script> <script src="../WebResources/new_jquery_1.9.1.min" type="text/javascript"></script> <script type="text/javascript"> function getLoggedInUserRoles() { var context = GetGlobalContext(); var userRecordId = parent.Xrm.Page.data.entity.getId(); retrieveMultiple("SystemUserSet", "?$select=systemuserroles_association/Name&$expand=systemuserroles_association&$filter=SystemUserId eq (guid'" + userRecordId + "')", getSecurityRoleNames, null, null); } function retrieveMultiple(odataSetName, filter, successCallback, errorCallback, _executionObj) { var context = GetGlobalContext(); var serverUrl = context.getServerUrl(); var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc"; //odataSetName is required, if (!odataSetName) { alert("odataSetName is required."); return; } //Build the URI var odataUri = serverUrl + ODATA_ENDPOINT + "/" + odataSetName; //If a filter is supplied, append it to the OData URI if (filter) { odataUri += filter; } //Asynchronous AJAX function to Retrieve CRM records using OData $.ajax({ type: "GET", async: true, contentType: "application/json; charset=utf-8", datatype: "json", url: odataUri, beforeSend: function (XMLHttpRequest) { //Specifying this header ensures that the results will be returned as JSON. XMLHttpRequest.setRequestHeader("Accept", "application/json"); }, success: function (data, textStatus, XmlHttpRequest) { if (successCallback) { if (data && data.d && data.d.results) { successCallback(data.d.results, textStatus, XmlHttpRequest); } else if (data && data.d) { successCallback(data.d, textStatus, XmlHttpRequest); } else { successCallback(data, textStatus, XmlHttpRequest); } } }, error: function (XmlHttpRequest, textStatus, errorThrown) { if (errorCallback) errorCallback(XmlHttpRequest, textStatus, errorThrown); else errorHandler(XmlHttpRequest, textStatus, errorThrown); } }); } function errorHandler(xmlHttpRequest, textStatus, errorThrow) { alert("Error : " + textStatus + ": " + xmlHttpRequest.statusText); } function getSecurityRoleNames(data, textStatus, XmlHttpRequest) { var totalCount = data[0].systemuserroles_association.results.length; var userString = null; if (totalCount > 0) { userString = ""; for (var i = 0; i < totalCount; i++) userString = userString + data[0].systemuserroles_association.results[i].Name + "\n"; document.getElementById("userRoles").innerText = userString; } else alert("No role associated with the user"); } </script> <style> h5 { font-family: Segoe UI,Tahoma,Arial; font-weight: bold; font-variant: normal; color: #000080; text-decoration: underline; } p { font-family: Segoe UI,Tahoma,Arial; font-size: 13px; } </style> <table> <tr><td><h5>Security Roles</h5></td></tr> <tr><td><p id="userRoles"></p></td></tr> <tr><td> </td></tr><tr> <td><button onclick="getLoggedInUserRoles()">Click here</button></td></tr> </table> </body> </html>
Step 5: Save and Publish “new_userRolesHTML” Webresource.
Step 6: Goto Microsoft Dynamics CRM –> Settings –> Customization –> Customize the System.
Step 7: Under Entities –> User –> Forms, open Information form as highlighted below,
Step 8: Click on Web Resource, under Insert tab on User Information form,
Step 9: Select the HTML webresource created in Step 3, and provide the name & Label as shown below,
Step 10: Click on Ok. Save & Publish the Form.
Step 11: Open any User record, and click on Click Here button to see the User Roles.
Happy Coding 🙂
Please share your feedback.
Calculate difference between Actual Start & Actual End in Minutes
Task: Calculate difference between Actual Start Date & Actual End Date in minutes and Setvalue in Duration field onSave of Phone Call entity
Solution: Follow the below steps,
Step 1: Create Javascript Webresource “new_phoneCallJscript”. Copy and paste the below code in Javascript Webresource,
Step 2: Call the function calculateDurationinMinutes onSave of phonecall entity
function calculateDurationinMinutes() { var actualStartObj = Xrm.Page.getAttribute("actualstart"); var actualEndObj = Xrm.Page.getAttribute("actualend"); var durationinMinutesObj = Xrm.Page.getAttribute("actualdurationminutes"); if (actualStartObj != null && actualEndObj != null && durationinMinutesObj != null) { var actualStart = actualStartObj.getValue(); var actualEnd = actualEndObj.getValue(); if (actualStart != null && actualEnd != null) { var dateDifference = Math.abs(actualEnd - actualStart); var durationInMinutes = Math.floor((dateDifference / 1000) / 60); durationinMinutesObj.setValue(durationInMinutes); } } }
Step 3: Save and Publish the Phone Call Activity. Open any Phone Call record and Select the value Actual Start and Actual End and click on Save to see the result in Duration field.
Please provide your valuable feedback on this article.
FetchXML Formatter Tool
It is a Light weight windows application and this tool will be helpful when you are extensively working with FetchXML in Javascript / C# code to get desired result.
Functionality:
It will take FetchXML from Advance Find as an input and convert that into desired format, which can be used into Javascript / C# for further coding.
Pros:
- No Need to spend time for FetchXML formatting
- It is easy to use.
- Works for both Javascript and C# code
Example:
Let us take a simple example of the below FetchXML,
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false"> <entity name="contact"> <attribute name="fullname" /> <attribute name="telephone1" /> <attribute name="emailaddress1" /> <attribute name="contactid" /> <order attribute="fullname" descending="false" /> <filter type="and"> <condition attribute="ownerid" operator="eq-userid" /> <condition attribute="statecode" operator="eq" value="0" /> </filter> </entity> </fetch>
Provide this as an input to FetchXML formatter Tool, 1. Check Javascript radio button and click on Format to see the below output,
"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>"+ " <entity name='contact'>"+ " <attribute name='fullname' />"+ " <attribute name='telephone1' />"+ " <attribute name='emailaddress1' />"+ " <attribute name='contactid' />"+ " <order attribute='fullname' descending='false' />"+ " <filter type='and'>"+ " <condition attribute='ownerid' operator='eq-userid' />"+ " <condition attribute='statecode' operator='eq' value='0' />"+ " </filter>"+ " </entity>"+ "</fetch>"
2. Check C# radio button and click on Format to see the below output,
@"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'> <entity name='contact'> <attribute name='fullname' /> <attribute name='telephone1' /> <attribute name='emailaddress1' /> <attribute name='contactid' /> <order attribute='fullname' descending='false' /> <filter type='and'> <condition attribute='ownerid' operator='eq-userid' /> <condition attribute='statecode' operator='eq' value='0' /> </filter> </entity> </fetch>"
Click Here to download the FetchXML Formatter Tool Exe file
Screen Shots:
Retrieve records using Fetch XML & Java Script in CRM 2011/13
Task: Retrieve Arun Potti Business Phone on onload of Contact record in Contact Entity using FetchXML & Javascript
Solution:
Step 1: Goto http://xrmsvctoolkit.codeplex.com/, and download the Zip folder. Unzip XrmServiceToolkit the folder.
Step 2: Open the XrmServiceToolkit folder, you can find the below Javascript files.
Goto Microsoft Dynamics CRM –> Settings –> Customization –> Webresources.
Create jquery, json2 and XrmServiceToolkit javascript webresources. While creating web resources browse for the respective files and provide the path of XRMServiceToolkit.
Step 3: Add all 3 files to the contact entity,
Step 4: Goto Microsoft Dynamics CRM –> Sales –> Contacts, click on Advance find button. Create new criteria as shown below by clicking on New button,
Step 5: Click on Download Fetch XML button, to get FetchXML code. You can see the below XML,
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false"> <entity name="contact"> <attribute name="fullname" /> <attribute name="telephone1" /> <attribute name="contactid" /> <order attribute="fullname" descending="false" /> <filter type="and"> <condition attribute="fullname" operator="eq" value="Arun Potti" /> </filter> </entity> </fetch>
Step 6: We have to change the format of the above FetchXML to use in Javascript.
Use FetchXML Formatter Tool to modify the format.
To Know more about FetchXML Formatter Tool click Here
After modifying its looks like the below,
"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>"+ " <entity name='contact'>"+ " <attribute name='fullname' />"+ " <attribute name='telephone1' />"+ " <attribute name='contactid' />"+ " <order attribute='fullname' descending='false' />"+ " <filter type='and'>"+ " <condition attribute='fullname' operator='eq' value='Arun Potti' />"+ " </filter>"+ " </entity>"+ "</fetch>"
Step 7: Now create new_contactJscript Webresource and paste the below code,
function contactOnload() { var contactFetchXML = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>"+ " <entity name='contact'>"+ " <attribute name='fullname' />"+ " <attribute name='telephone1' />"+ " <attribute name='contactid' />"+ " <order attribute='fullname' descending='false' />"+ " <filter type='and'>"+ " <condition attribute='fullname' operator='eq' value='Arun Potti' />"+ " </filter>"+ " </entity>"+ "</fetch>"; var contactRecords = XrmServiceToolkit.Soap.Fetch(contactFetchXML); if (contactRecords.length > 0) { if (contactRecords[0].attributes.telephone1 != undefined) alert(contactRecords[0].attributes.telephone1.value); } }
Step 8: Add the new_contactJscript Webresource to Form Libraries on contact Form, and add the contactOnload function to Onload Event,
Step 9: Click on Ok. Save & Publish the contact Entity.
Step 10: Open the existing contact record to see the below pop up,
Enable / Disable Header Field on CRM form 2013
To access header fields using JavaScript, use header keyword before field schema name.
To Disable Or Readonly:
Xrm.Page.getControl("header_<schemaname>").setDisabled(true);
To Enable:
Xrm.Page.getControl("header_<schemaname>").setDisabled(false);
Hope it helps 🙂
Get Logged In User Security Roles using Javascript OData 2013
Using OData, will see an example to retrieve Security Roles of Logged In User.
Task: Retrieve Logged In User Security Roles on Onload of Contact Entity
Solution:
Step 1: Include Json2 web resource in the Contact Entity.
If you don’t have this file, download Latest SDK and go to below path and create,
\CRM SDK\SDK\SampleCode\JS\RESTEndpoint\JavaScriptRESTDataOperations\JavaScriptRESTDataOperations\Scripts
Step 2: Create new JavaScript web resource (Ex: new_contact) and include the below script,
function getLoggedInUserRoles() { var Id = Xrm.Page.context.getUserId(); retrieveMultiple("SystemUserSet", "?$select=systemuserroles_association/Name&$expand=systemuserroles_association&$filter=SystemUserId eq (guid'" + Id + "')", getSecurityRoleNames, null, null); } function retrieveMultiple(odataSetName, filter, successCallback, errorCallback, _executionObj) { var context = Xrm.Page.context; var serverUrl = context.getServerUrl(); var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc"; //odataSetName is required, i.e. "AccountSet" if (!odataSetName) { alert("odataSetName is required."); return; } //Build the URI var odataUri = serverUrl + ODATA_ENDPOINT + "/" + odataSetName; //If a filter is supplied, append it to the OData URI if (filter) { odataUri += filter; } //Asynchronous AJAX function to Retrieve CRM records using OData $.ajax({ type: "GET", async: true, contentType: "application/json; charset=utf-8", datatype: "json", url: odataUri, beforeSend: function(XMLHttpRequest) { //Specifying this header ensures that the results will be returned as JSON. XMLHttpRequest.setRequestHeader("Accept", "application/json"); }, success: function(data, textStatus, XmlHttpRequest) { if (successCallback) { if (data && data.d && data.d.results) { successCallback(data.d.results, textStatus, XmlHttpRequest); } else if (data && data.d) { successCallback(data.d, textStatus, XmlHttpRequest); } else { successCallback(data, textStatus, XmlHttpRequest); } } }, error: function(XmlHttpRequest, textStatus, errorThrown) { if (errorCallback) errorCallback(XmlHttpRequest, textStatus, errorThrown); else errorHandler(XmlHttpRequest, textStatus, errorThrown); } }); } function errorHandler(xmlHttpRequest, textStatus, errorThrow) { alert("Error : " + textStatus + ": " + xmlHttpRequest.statusText); } function getSecurityRoleNames(data, textStatus, XmlHttpRequest) { var totalCount = data[0].systemuserroles_association.results.length; var userString = null; if (totalCount > 0) { userString = "User Role : "; for (var i = 0; i < totalCount; i++) userString = userString + data[0].systemuserroles_association.results[i].Name + "\n"; alert(userString); } else alert("No Role Associated with LoggedIn User"); }
Step 3: Add new_contact Jscript web resource in the Contact Entity. Add getLoggedInUsersRoles function on Onload of Contact.
Step 4: Click on Ok. Save and Publish Contact Entity.
Step 5: Open any Contact record and see the below Popup.
Please provide your valuable comments on this article.