RSS

Tag Archives: Ranjan Parhi

CRM 2013 Multi Pick List

Background

In One of our previous Blogs CRM 2011 Multi Pick list, we have discussed about creating Multiple Pick List in the MS Dynamic CRM form. But the previous post was for CRM 2011. As the CRM 2013 is supported across different browsers, we have to change a little in the code to make it compatible for all major browsers. Here is the modified Blog for Multi Pick List in MS Dynamics CRM 2013.

Let’s start

In this article, we will create a Multiple Pick List for Dynamic CRM form. User can enter multiple data from Pick List by CheckBox. This will also work on all the four major browsers (IE, Firefox, Chrome and Safari).
5-1-2013 1-35-04 PM

Requirement

There was a requirement in a project, where user wanted to select, not only one, but also multiple value from a Pick List.

Solution

Steps which are needed to be followed:-

  1. Creation of Field.
  2. Create Web Resource.
  3. Add function to the form.

Creation of Field

There are two fields which are created on the entity you want to make Multi Pick List :-

  1. OptionSet Field :- all the option which must be entered
  2. Data Field:- Multiple Lines of Text Field. In which data is stored.

Include both the field on the form.

Create Web Resource

Create a Web Resource with the following code:-

// var_sc_optionset >>  Provide logical-name for Option Set field
// var_sc_optionsetvalue >> Provide logical-name for field which will
//                          store the multi selected values for Option Set
// OS >> Provide Options of the Optionset field
//       (Ex:- Xrm.Page.getAttribute("Option Set field logical-name").getOptions())
// OSV >> Provide text field object which will store the
//        multi selected values for Option Set
//       (Ex:- document.getElementById("text field logical-name"))

// Method to convert an optionset to multi select OptionSet
function ConvertToMultiSelect(var_sc_optionset, var_sc_optionsetvalue, OS, OSV) {

    if (OS != null && OSV != 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;
        var maxValue = 0;

        var nAgt = navigator.userAgent;

        if (nAgt.indexOf("Firefox") != -1) {  // If the broswer is "Firefox" 

            initialValue = 1;
            maxValue = OS.length;

        }
        else if (nAgt.indexOf("Chrome") != -1 || nAgt.indexOf("IE") != -1) { // If the browser is Chrome or IE

            initialValue = 0;
            maxValue = OS.length - 1;
        }
        else if (nAgt.indexOf("Safari") != -1) {  // If the browser id "Safari"

            initialValue = 1;
            maxValue = OS.length;
        }

        // Initialise checkbox controls
        for (var i = initialValue; i < maxValue; i++) {
            var pOption = OS[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);
    var options = Xrm.Page.getAttribute(optionSet).getOptions();
    var getInput = OS.nextSibling.getElementsByTagName("input");
    var result = "";
    var 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 id "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);
    var c_OptionValue = Xrm.Page.getControl(var_sc_optionsetvalue);
    var 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%;'>";
        var OptionValueV = OptionValue.getValue();

        var OptionValueT = OptionValueV.split(",");
        var 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;
    }  
}

Add function to the form

There are three functions need to be added

  • On Load :-

    1. Function name :- ConvertToMultiSelect.
      Parameter :- “new_multipicklistoption”, “new_multipicklistvalue”, Xrm.Page.getAttribute(“new_multipicklistoption”).getOptions(), document.getElementById(“new_multipicklistvalue”)
    2. Function name :- createTable
      Parameter :- “new_multipicklistvalue”.

5-1-2013 1-11-58 PM

  • On Save :-

    1. Function Name :- OnSave
      Parameter :- “new_multipicklistoption”, “new_multipicklistvalue”

5-1-2013 1-12-52 PM

Reference

CRM 2011 Multi Pick list

By Ranjan Parhi
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

Advertisements
 
2 Comments

Posted by on January 30, 2014 in WebResources

 

Tags: , , , , , , , , , , , , , , , , , , , , , ,

Custom WorkFlow to Send Email with PDF formatted Report as Attachment

Introduction

In some cases, we have to send Email to customers with a Report in Pdf format as an attachment.

Background

Once I had the same requirement. To do this, we have to follow three steps.

  1. First to retrieve the Report,
  2. Second to convert the Report to Pdf format and
  3. Last to send an Email with the Pdf as attachment.

Code

To achieve this, I have written a Custom Workflow.
Here is the code snippet to get it done. This code is for CRM OnPremise only. I have not tried in CRM Online.

using System;
using System.Activities;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Crm.Sdk.Messages;
using CustomWorkflows.ReportService; //Have to add the Reporting Service as Web Reference

namespace SendReport
{
    public class SendReport : CodeActivity
    {
        protected override void Execute(CodeActivityContext executionContext)
        {
            try
            {
                IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
                IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

                Guid accountId = context.PrimaryEntityId;
                byte[] result = null;

                CustomWorkflows.ReportService.ReportExecutionService rs = new ReportExecutionService();

                // Credential to connect with CRM
                rs.Credentials = new System.Net.NetworkCredential(username, password, domain);

                // Setting the URL of the Reporting Server
                rs.Url = "http://test10:80/ReportServer/ReportExecution2005.asmx";

                string reportPath = "/Test_MSCRM/TestReport";
                // Specify the report path from the reporting server
                // Note: To get the report name, report must be published for the external use.
                // To do this edit the report from CRM and publish it for external use.
                // After publishing it for external use report name will be visible in the reporting server instead of the report id.

                string format = "PDF";
                string historyID = null;
                string devInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
                string encoding;
                string mimeType;
                string extension;
                Warning[] warnings = null;
                string[] streamIDs = null;

                ExecutionInfo execInfo = new ExecutionInfo();
                ExecutionHeader execHeader = new ExecutionHeader();
                rs.ExecutionHeaderValue = execHeader;
                execInfo = rs.LoadReport(reportPath, historyID);

                String SessionId = rs.ExecutionHeaderValue.ExecutionID;

                result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);

                //Create email activity
                Entity email = new Entity();
                email.LogicalName = "email";
                email.Attributes.Add("regardingobjectid", new EntityReference("account", accountId);

                //Creating EntityReference for from, to and cc. Need to be changed according to your requirement
                EntityReference from = new EntityReference("systemuser", senderUserId);
                EntityReference to = new EntityReference("contact", recieverUserId);
                EntityReference cc = new EntityReference("contact", recieverCCUserId);

                //Creating party list
                Entity fromParty = new Entity("activityparty");
                fromParty.Attributes.Add("partyid", from);
                Entity toParty = new Entity("activityparty");
                toParty.Attributes.Add("partyid", to);
                Entity ccParty = new Entity("activityparty");
                ccParty.Attributes.Add("partyid", cc);

                EntityCollection collFromParty = new EntityCollection();
                collFromParty.EntityName = "systemuser";
                collFromParty.Entities.Add(fromParty);

                EntityCollection collToParty = new EntityCollection();
                collToParty.EntityName = "contact";
                collToParty.Entities.Add(toParty);

                EntityCollection collccParty = new EntityCollection();
                collccParty.EntityName = "contact";
                collccParty.Entities.Add(ccParty);

                // Adding from, to and cc to the email
                email.Attributes.Add("from", collFromParty);
                email.Attributes.Add("to", collToParty);
                email.Attributes.Add("cc", collccParty);

                email.Attributes.Add("subject", "Here goes subject message.. : ");
                email.Attributes.Add("description", "Here goes description text..");
                Guid emailID = service.Create(email); // Create the email

                // Attaching Pdf Report
                int NextActorID = new int();
                RetrieveEntityRequest request = new RetrieveEntityRequest();
                request.LogicalName = "email";
                RetrieveEntityResponse response = (RetrieveEntityResponse)service.Execute(request);
                int objecttypecode = response.EntityMetadata.ObjectTypeCode.Value;

                Entity attachment = new Entity("activitymimeattachment");
                attachment.Attributes.Add("subject", "Report");
                attachment.Attributes.Add("filename", "Report.pdf");
                attachment.Attributes.Add("body", Convert.ToBase64String(result));
                attachment.Attributes.Add("filesize", Convert.ToInt32(result.Length.ToString()));
                attachment.Attributes.Add("mimetype", "text/plain");
                attachment.Attributes.Add("attachmentnumber", NextActorID);
                attachment.Attributes.Add("objectid", new EntityReference("email", new Guid(email.Id.ToString())));
                attachment.Attributes.Add("objecttypecode", objecttypecode);
                service.Create(attachment); //Create the attachment

                // Sending email
                SendEmailRequest reqSendEmail = new SendEmailRequest();
                reqSendEmail.EmailId = emailID;
                reqSendEmail.TrackingToken = "";
                reqSendEmail.IssueSend = true;
                SendEmailResponse res = (SendEmailResponse)service.Execute(reqSendEmail);
            }
            catch (Exception err)
            {
                // Throw error message
            }
        }
    }
}

By Ranjan Parhi
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

 
9 Comments

Posted by on November 20, 2013 in CRM WorkFlow

 

Tags: , , , , , , , , , , , , , , , ,

Changing Filter Condition in Associated View

Activities Associated View

Activities Associated View

Introduction

At times, we have the requirement to change the Filter Condition in an Associated View.

Background

In my case, the requirement was to show all the Activities when “Activities” Associated View is selected. The default Filter Condition in Activity Associated View is “Next 30 days“. I had to change it to “All“.

Code

Here is the code snippet to work this out. This function must be called on Load of the Form.

function filterAllActivities()
{
    //Calling function when activity is clicked
    document.getElementById("navActivities").onclick = function () {
        Mscrm.Details.loadArea(this, "areaActivities"); //loadArea is the predefined function

        //On load of the activity iframe change the filter
        document.getElementById("areaActivitiesFrame").onload = function () {
            var entityName = Xrm.Page.data.entity.getEntityName();
            var entity = entityName.charAt(0).toUpperCase() + entityName.substr(1);

            var doc = this.contentWindow.document; //Getting the document of the window

            //Getting the control of the 'Filter on' dropdown
            var filterOn = doc.getElementById("crmGrid_" + entity + "_ActivityPointers_datefilter");
            filterOn.value = "All"; //Changing the filter condition

            var evt = document.createEvent("HTMLEvents");
            evt.initEvent("change", false, true);
            filterOn.dispatchEvent(evt); //Dispatch event
        };
    };
}

By Ranjan Parhi
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

 
3 Comments

Posted by on November 19, 2013 in WebResources

 

Tags: , , , , , , , , , , , , , , ,

ExecuteMultipleRequest For Bulk Operation

Introduction

In the Microsoft Dynamics CRM 2011 Update Rollup 12, a new message request named ExecuteMultipleRequest is added. Let’s explore more about the usage.

What it does?

It accepts Collection of Requests as input and returns Collection of Responses. The request is executed batch by batch.

For Online CRM, maximum Batch Size is 1000. So, for Online CRM, maximum 1000 requests can be executed at a time.

For On Premise, Batch Size can be increased.

Example

Below are the examples of the ExecuteMultipleRequest.

  • Bulk Lead Creation

    //The method takes IOrganization service and total number of records to be created as input
     private void CreateLeadMultiple(IOrganizationService service, int batchSize)
     {
         //To execute the request we have to add the Microsoft.Xrm.Sdk of the latest SDK as reference
         ExecuteMultipleRequest req = new ExecuteMultipleRequest();
         req.Requests = new OrganizationRequestCollection();
         req.Settings = new ExecuteMultipleSettings();
         req.Settings.ContinueOnError = true;
         req.Settings.ReturnResponses = true;
    
         try
         {
             for (int i = 0; i < batchSize; i++)
             {
                 Entity lead = new Entity("lead");
                 lead["subject"] = "Test Lead";
                 lead["firstname"] = "Requested Lead";
                 lead["lastname"] = "Name " + i;
                 var createRequest = new CreateRequest();
    
                 createRequest.Target = lead;
                 req.Requests.Add(createRequest);
              }
    
              var res = service.Execute(req) as ExecuteMultipleResponse;  //Execute the collection of requests
          }
    
          //If the BatchSize exceeds 1000 fault will be thrown.In the catch block divide the records into batchable records and create
          catch (FaultException<OrganizationServiceFault> fault)
          {
              if (fault.Detail.ErrorDetails.Contains("MaxBatchSize"))
              {
                  var allowedBatchSize = Convert.ToInt32(fault.Detail.ErrorDetails["MaxBatchSize"]);
                  int remainingCreates = batchSize;
    
                  while (remainingCreates > 0)
                  {
                      var recordsToCreate = Math.Min(remainingCreates, allowedBatchSize);
                      CreateLeadMultiple(service, recordsToCreate);
                      remainingCreates -= recordsToCreate;
                  }
              }
          }
    }
    
  • Bulk Entity State and Status Change

    Here is another example of changing the State and Status of records by ExecuteMultipleRequest.

    This code will work, if the total Records <=1000, otherwise we have to break the records into batches to execute one by one.

    for (int i = count; i < ent.Entities.Count; i++)
    {
        SetStateRequest changeState = new SetStateRequest();
        changeState.EntityMoniker = new EntityReference();
        changeState.EntityMoniker.Id = ent.Entities[i].Id;
        changeState.EntityMoniker.LogicalName = ent.Entities[i].LogicalName;
        changeState.State = new OptionSetValue(0);
        changeState.Status = new OptionSetValue(1);
        req.Requests.Add(changeState);
    }
    
    // Here req is the object of ExecuteMultipleRequest class.
    var res = service.Execute(req) as ExecuteMultipleResponse;
    

By Ranjan Parhi
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

 
1 Comment

Posted by on August 7, 2013 in SDK Messages

 

Tags: , , , , , , , , , , , , , , , ,

Filtering Lookup depending upon the OptionSet value

Introduction

We can filter the look up field depending upon the value in OptionSet field using javaScript.

Background

In our case, we have two entities “Account” and “Test”, which have 1:N relationship.
An OptionSet field “new_profession” and a lookup of the “Test” entity are present in “Account” entity.
To retrieve the filtered records depending upon the option selected in the “new_profession” field, we will implement a JScript on the load event of Account entity and OnChange event of the “new_profession” field in Account entity.

Code

function FilteredLookup() {

    var viewId = "{a76b2c46-c28e-4e5e-9ddf-951b71202c9d}"; //Any Guid is fine.
    var entityName = "new_test";// Entity to be filtered
    var profession = Xrm.Page.data.entity.attributes.get("new_profession").getValue();

    if(profession != null && profession != "")
    {
        //Name for the lookup field.
        Xrm.Page.ui.controls.get("new_test_testid").setDisabled(false);

        //Custom Name for the lookup window
        var viewDisplayName = Xrm.Page.data.entity.attributes.get("new_profession").getSelectedOption().text;

        var fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
                          "<entity name='new_test1'>" +
                              "<attribute name='new_name' />" +
                              "<attribute name='new_profession' />" +
                              "<order attribute='new_name' descending='false' />" +
                              "<filter type='and'>" +
                                "<condition attribute='new_profession' operator='eq' value='" + profession + "' />" +
                              "</filter>" +
                          "</entity>" +
                       "</fetch>";

        var layoutXml = "<grid name='resultset' " +
                            "object='1' " +
                            "jump='name' " +
                            "select='1' " +
                            "icon='1' " +
                            "preview='1'>" +
                            "<row name='result' " +
                                "id='new_test1id'>" + // Id attribute of the entity to be filtered
                                "<cell name='new_name' " + //Column 1 – Fullname
                                "width='100' />" +
                                "<cell name='new_profession' " + //Column 2- Profession
                                "width='100' />" +
                            "</row>" +
                        "</grid>";

        //Part3 add new view to the lookup
        Xrm.Page.getControl("new_test1_testid").addCustomView(viewId, entityName, viewDisplayName, fetchXml, layoutXml, true);
    }
}

By Ranjan Parhi
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

 

Tags: , , , , , , , , , , , , , ,

Adding Tool Tips To Fields

Introduction

Tool tips can be added to the fields of the CRM form. It can be a static or dynamic tool tip.

Implementation

To implement this logic, we need Jquery.1.4.4.min.js file. You can get from here .

Create a  javascript web resource and add following functions in it.

function GetToolTips() {
    //Select Name Of Fields Whose ToolTips Is Recquird
    var fieldName1 = "telephone1";
    var fieldName2 = "telephone2";
    var fieldName3 = "fax";

    //Create Text To Be Shown In Respected Fields
    var textOfFieldName1 = "Tool Tip One";
    var textOfFieldName2 = "Tool Tip Two";
    var textOfFieldName3 = "Tolo Tip Three";

    //Calling Method To set Text On That Label Of Selected Field
    RegisterTips(fieldName1, textOfFieldName1);
    RegisterTips(fieldName2, textOfFieldName2);
    RegisterTips(fieldName3, textOfFieldName3);
}

function RegisterTips(fieldName, textOfField) {
    var obj = document.getElementById(fieldName + '_c').children[0];

    // construct tooltip text according to attribute name
    html = '</pre>
<div id="tooltip_' + fieldName + '" style="visibility: hidden; position: absolute;">: ' + textOfField + '</div>
<pre>
';

    $(obj).append(html); // append tooltip text with label
}

Add  jquery.1.4.4.min.js file as web resource.

In the “account” form property, add  both the Web Resources.

In the Onload event of  the account form call the GetToolTips() function and see the tool tip will be reflected when the mouse points to that fields as shown below.

Capture capture2

Hope it helps you……

By Ranjan Parhi
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

 
 

Tags: , , , , , , , , , , , , , , , , ,

 
%d bloggers like this: