Multi Option Set / Picklist in CRM 2011 / 13 / 15 using Javascript

50th Article

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

OptionSet Values

Solution: Follow the below steps to select multi Option Set / Picklist values in CRM,

Step 1: Create below fields in Contact form,

50 - Field Schema Names

50 - Option Set Field

50 - Option Set Field Values

Step 2: Place the 2 fields on the required place on contact form, and uncheck Visible by default for “Sport Option Set Values” field.

50 - Form Properties - Option Set Field Values

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“.

50 - OnLoad

Step 5: Select Library “new_multiPickList” and provide the function name “OnSave” on OnSave Event.

Provide the parameters “new_favouritesport“, “new_sportoptionsetsvalues“.

50 - OnSave

Step 6: Save & Publish Contact Form. Open any CRM record to see the below Output,

Download JavaScript Code

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

Jquery_1.9.1.min
Step 2: Browse for jquery_1.9.1.min and Create “new_ jquery_1.9.1.min” Jscript Webresource as shown below,

Jquery_1.9.1.min Webresource

Step 3: Create HTML Webresource “new_userRolesHTML”,

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,

User Form

Step 8: Click on Web Resource, under Insert tab on User Information form,

Create Webresource

Step 9: Select the HTML webresource created in Step 3, and provide the name & Label as shown below,

new_userRolesHTML under User Form

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.

Final Output

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:

  1. No Need to spend time for FetchXML formatting
  2. It is easy to use.
  3. 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:

FetchXMLFormatter - Pic 1
FetchXMLFormatter - Pic 2
FetchXMLFormatter - Pic 3
FetchXMLFormatter - Pic 4
Please provide your valuable feedback on this article.

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.

FetchXML - Pic 1

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,

FetchXML - Pic 2

Step 4: Goto Microsoft Dynamics CRM –> Sales –> Contacts, click on Advance find button. Create new criteria as shown below by clicking on New button,

FetchXML - Pic 3

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,

FetchXML - Pic 5

Step 9: Click on Ok. Save & Publish the contact Entity.

Step 10: Open the existing contact record to see the below pop up,

FetchXML - Pic 6

 

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 🙂