on Tuesday, 30 April 2013
Recently I was working on a project that required a lot of plugins and workflows to carry out a variety of calculations on data, however the calculations made use of a lot of variables that changed regularly (a few times a week say).
Therefore, the values could not be hard-coded by the plugins and needed to be easily editable by the users.  Initially I thought parameters would be the solution to this problem, the users could simply go in to the customisations and change them?  Then I thought of a much cleaner way to achieve the same functionality, a configuration entity.  The use of a configuration entity solves 3 problems here, firstly the everyday system users should never have to go into the customisations and make changes on a regular basis, even if they are just to process parameters.  Also, a lot of the same parameter values were being used in several different processes and plugins and related to that, plugins can't have parameters in the same way as workflow processes.

The idea is that you create an entity with a field for each value required, users can then access this entity in the front-end system and change the values to be used in the processes.  The processes access the parameters stored in the configuration record(s) by performing a simple retrieve on the configuration record(s) required and storing the required values in variables at the start of each execution.

This concept could obviously be applied in any Dynamics CRM system that had to make use of regularly changed values in its processes and plugins.
on Saturday, 27 April 2013

In this article I am going to show you, step-by-step, how to auto-number your records in Microsoft Dynamics CRM 2011.

* This article assumes you already have your environment set up.


  • First, create a new solution with a name of your choice (I've called mine "JacksSolution").
  • Create an option set in the solution called 'Prefix & Suffix Options', and give it the following options:

Option Set Options
Free Text
2-Digit
4-Digit

  • Create a new entity called 'Auto-number'.
  • Create the following fields on the entity:

Display NameField TypeSchema Name
Entity NameSingle Line of Textjack_entity
Field NameSingle Line of Textjack_field
CounterWhole Numberjack_counter
Increment UnitWhole Numberjack_incrementunit
Number FormatterSingle Line of Textjack_numberformatter
PrefixSingle Line of Textjack_prefix
SuffixSingle Line of Textjack_suffix
Prefix SeparatorSingle Line of Textjack_prefixseparator
Suffix SeparatorSingle Line of Textjack_suffixseparator
Prefix TypeOption Setjack_prefixtype
Suffix TypeOption Setjack_suffixtype

  • Arrange the fields neatly on the form, like so:

  • In this example we are going to automatically number the Invoice entity, so go to the Invoice entity, add a field called 'Invoice ID' of type single-line of text and place it somewhere obvious on the form.
  • Now, create a new JavaScript web-resource with a name of your choice and add the following JavaScript from the linked file to the file in CRM:

  • Go back to the Auto-number entity and call the AutonumberOnLoad function on-load of the form.
  • Also add the OnPrefixSuffixTypeChange function to the on-change event of both the 'Prefix Type' field and the 'Suffix Type' field and pass in the name of the calling field in string format as the parameter (in my case 'jack_prefixtype' and 'jack_suffixtype').
  • Create a new auto-number record in the system and fill in the details, I used the following:

  • Now comes the plugin itself, you will have to create one for each entity you wish to automatically number.  
  • For this example, create a new plugin to fire pre-operation on-create of the invoice entity and add the code found in the following text file:


  • Deploy the plugin to the auto-number solution.
  • Now, create a new invoice and hey-presto, its been numbered!

This component can be easily modified to work with any entity in the system, including custom entities.
on Wednesday, 17 April 2013


If you are using Microsoft Dynamics CRM 2011 On-Premise on a Windows 8 machine running IE 10, it is likely you are having a range of issues affecting your system (sometimes preventing you from using it completely).  I'm not going to go through these issues, I'm just going to show you how to fix it *.

Heres what you need to do:

  1. Right-click the toolbar running along the top of the browser window.
  2. Select 'Menu Bar'.
  3. In the Menu Bar that has just appeared, select 'Tools'.
  4. In Tools, select 'Compatibility View Settings'.
  5. In here, you can either select 'Display All Websites In Compatibility View' or enter in the URL of your CRM 2011 on-premise environment.


* This fix should only be used if you don't have access to Rollup 12.  If you do, apply it and your problems should be resolved.
on Tuesday, 16 April 2013


In this tutorial I'm going to show you how to place an address lookup button on the contact form.

First, create a new solution in your environment and add the 'Contact' entity to it from the default solution (you are going to edit it later).
Next, download the JQuery library from here :

http://jquery.com/download/

You'll need to add this to your solution in the form of a JavaScript web-resource.  To do so, create a new web-resource in the solution and give it an appropriate name, make it of type JavaScript, copy and paste the JavaScript from the downloaded JQuery file into the text editor and save it.

Next, create another new JavaScript web-resource file, and call it something like 'Address Lookup Library'.  Add the following JavaScript in the text editor and save it:

//***********************
//Contact Functions
//***********************
function contactsOnLoad() {
  addButton('address1_addresstypecode')
}

function addButton(attributename) {
    if (document.getElementById(attributename) != null) {
        var sFieldID = "field" + attributename;
        var elementID = document.getElementById(attributename + "_d");
        var div = document.createElement("div");
        div.style.width = "100%";
        div.style.textAlign = "left";
        div.style.display = "inline";
        elementID.appendChild(div, elementID);
        div.innerHTML = '';
        document.getElementById(attributename).style.width = "100%";
        document.getElementById(sFieldID).onclick = function () {CustomLookup(); };
    }
}

//***********************
//Contact Address Lookup Functions
//***********************
function CustomLookup() {
  //Get value of the selected customer account
  var lookupItem = Xrm.Page.getAttribute("parentcustomerid").getValue();
  
  if (lookupItem != null)
  {
    // Lookup Customer info
    //On-line
    //var url = '/_controls/lookup/lookupsingle.aspx?class=BrowseCustomerAddress&objecttypes=1071&browse=1//&bindingcolumns=line1%2cpostalcode&parentType='
//        + lookupItem[0].type + '&parentId='
//        + lookupItem[0].id + '&ShowNewButton=1&ShowPropButton=1//&DefaultType=1071';

    //On-premise
    var url = '/' + Xrm.Page.context.getOrgUniqueName() +
      '/_controls/lookup/lookupsingle.aspx?class=BrowseCustomerAddress&objecttypes=1071&browse=1&bindingcolumns=line1%2cpostalcode&parentType='
        + lookupItem[0].type + '&parentId='
        + lookupItem[0].id + '&ShowNewButton=1&ShowPropButton=1&DefaultType=1071';


    // shows a modal window to select the addresses
    var selectedAddress = window.showModalDialog(url, null, 'dialogWidth:600px;dialogHeight:400px;resizable:yes');
    
    // Validate address info in not null before continuing
    if (selectedAddress != null)
    {
      var addressFields =  jQuery.parseJSON(selectedAddress);
      // we have the id of the address - now use the json to get the values in an array.
      if (addressFields.items != null)
{
 var sLookupValue = addressFields.items[0].id;
      var xml = "" + "" + "" + decodeURI(GenerateAuthenticationHeader()) + " " + " " + " " +
                         " customeraddress" +
     " " +
     " " +
     " city" +
     " country" +
     " fax" +
     " line1" +
     " line2" +
     " line3" +
     " name" +
     " postalcode" +
     " primarycontactname" +
     " stateorprovince" +
     " telephone1" +
     " " +
     " " +
     " " +
     " customeraddressid" +
     " " +
     " " +
     " " + sLookupValue + "" +
     " " +
     " " +
     " " +
     " " +
     " " + "";

var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
      xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
      xmlHttpRequest.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple");
      xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
      xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
      xmlHttpRequest.send(xml);

      var resultXML = xmlHttpRequest.responseXml;

      //alert(xmlHttpRequest.responseText);
      var oXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
      oXmlDoc.async = false;
      oXmlDoc.loadXML(resultXML.xml);

      var businessEntities = oXmlDoc.getElementsByTagName('BusinessEntity');
                    
      for (i=0; i< 1; i++)
      {
        if (businessEntities[i].selectSingleNode('./q1:name') != null)
        {
          // Address Name Set
          Xrm.Page.getControl("address1_name").setDisabled(false);
          Xrm.Page.getAttribute("address1_name").setValue(businessEntities[i].selectSingleNode('./q1:name').text);
          Xrm.Page.getAttribute("address1_name").setSubmitMode("always");
          //Xrm.Page.getControl("address1_name").setDisabled(true);

          if (businessEntities[i].selectSingleNode('./q1:city') != null) {
            // Address City set
            Xrm.Page.getControl("address1_city").setDisabled(false);
            Xrm.Page.getAttribute("address1_city").setValue(businessEntities[i].selectSingleNode('./q1:city').text);
            Xrm.Page.getAttribute("address1_city").setSubmitMode("always");
            //Xrm.Page.getControl("address1_city").setDisabled(true);
          }
          else {
            // Address City set
            Xrm.Page.getControl("address1_city").setDisabled(false);
            Xrm.Page.getAttribute("address1_city").setValue(null);
            Xrm.Page.getAttribute("address1_city").setSubmitMode("always");
           // Xrm.Page.getControl("address1_city").setDisabled(true);
          }

          if (businessEntities[i].selectSingleNode('./q1:country') != null){
            // Country set
            Xrm.Page.getControl("address1_country").setDisabled(false);
            Xrm.Page.getAttribute("address1_country").setValue(businessEntities[i].selectSingleNode('./q1:country').text);
            Xrm.Page.getAttribute("address1_country").setSubmitMode("always");
            //Xrm.Page.getControl("address1_country").setDisabled(true);
          }
          else {
            // Country set
            Xrm.Page.getControl("address1_country").setDisabled(false);
            Xrm.Page.getAttribute("address1_country").setValue(null);
            Xrm.Page.getAttribute("address1_country").setSubmitMode("always");
            //Xrm.Page.getControl("address1_country").setDisabled(true);
          }               
          if (businessEntities[i].selectSingleNode('./q1:line1') != null){
            // Address Line 1 set
            Xrm.Page.getControl("address1_line1").setDisabled(false);
            Xrm.Page.getAttribute("address1_line1").setValue(businessEntities[i].selectSingleNode('./q1:line1').text);
            Xrm.Page.getAttribute("address1_line1").setSubmitMode("always");
            //Xrm.Page.getControl("address1_line1").setDisabled(true);
          }
          else {
            // Address Line 1 set
            Xrm.Page.getControl("address1_line1").setDisabled(false);
            Xrm.Page.getAttribute("address1_line1").setValue(null);
            Xrm.Page.getAttribute("address1_line1").setSubmitMode("always");
            //Xrm.Page.getControl("address1_line1").setDisabled(true);
          }

          if (businessEntities[i].selectSingleNode('./q1:line2') != null){
           // Address Line 2 set
           Xrm.Page.getControl("address1_line2").setDisabled(false);
           Xrm.Page.getAttribute("address1_line2").setValue(businessEntities[i].selectSingleNode('./q1:line2').text);
           Xrm.Page.getAttribute("address1_line2").setSubmitMode("always");
           //Xrm.Page.getControl("address1_line2").setDisabled(true);
         }
          else {
           // Address Line 2 set
           Xrm.Page.getControl("address1_line2").setDisabled(false);
           Xrm.Page.getAttribute("address1_line2").setValue(null);
           Xrm.Page.getAttribute("address1_line2").setSubmitMode("always");
           //Xrm.Page.getControl("address1_line2").setDisabled(true);
          }

         if (businessEntities[i].selectSingleNode('./q1:line3') != null){
           // Address Line 3 set
           Xrm.Page.getControl("address1_line3").setDisabled(false);
           Xrm.Page.getAttribute("address1_line3").setValue(businessEntities[i].selectSingleNode('./q1:line3').text);
           Xrm.Page.getAttribute("address1_line3").setSubmitMode("always");
           //Xrm.Page.getControl("address1_line3").setDisabled(true);
         }
          else {
           // Address Line 3 set
           Xrm.Page.getControl("address1_line3").setDisabled(false);
           Xrm.Page.getAttribute("address1_line3").setValue(null);
           Xrm.Page.getAttribute("address1_line3").setSubmitMode("always");
           //Xrm.Page.getControl("address1_line3").setDisabled(true);
          }

         if (businessEntities[i].selectSingleNode('./q1:postalcode') != null){
           //Address ZipCode set
           Xrm.Page.getControl("address1_postalcode").setDisabled(false);
           Xrm.Page.getAttribute("address1_postalcode").setValue(businessEntities[i].selectSingleNode('./q1:postalcode').text);
           Xrm.Page.getAttribute("address1_postalcode").setSubmitMode("always");
           //Xrm.Page.getControl("address1_postalcode").setDisabled(true);
         }
          else {
           //Address ZipCode set
           Xrm.Page.getControl("address1_postalcode").setDisabled(false);
           Xrm.Page.getAttribute("address1_postalcode").setValue(null);
           Xrm.Page.getAttribute("address1_postalcode").setSubmitMode("always");
           //Xrm.Page.getControl("address1_postalcode").setDisabled(true);
          }

         if (businessEntities[i].selectSingleNode('./q1:stateorprovince')!= null){
           //Address State set
           Xrm.Page.getControl("address1_stateorprovince").setDisabled(false);
           Xrm.Page.getAttribute("address1_stateorprovince").setValue(businessEntities[i].selectSingleNode('./q1:stateorprovince').text);
           Xrm.Page.getAttribute("address1_stateorprovince").setSubmitMode("always");
           //Xrm.Page.getControl("address1_stateorprovince").setDisabled(true);
         }
          else {
           //Address State set
           Xrm.Page.getControl("address1_stateorprovince").setDisabled(false);
           Xrm.Page.getAttribute("address1_stateorprovince").setValue(null);
           Xrm.Page.getAttribute("address1_stateorprovince").setSubmitMode("always");
          // Xrm.Page.getControl("address1_stateorprovince").setDisabled(true);
          }

}
     
       }// end if entity not empty
     }// end for i++
   }//end if no address selected
 }else {
     alert("No Parent Customer Selected.");
   }//  // end of if no customer seelcted
}// end of new address selected function

*Note: At the top of the function CustomLookup you'll notice there is a commented out section:

    //On-line
    //var url = '/_controls/lookup/lookupsingle.aspx?class=BrowseCustomerAddress&objecttypes=1071&browse=1//&bindingcolumns=line1%2cpostalcode&parentType='
//        + lookupItem[0].type + '&parentId='
//        + lookupItem[0].id + '&ShowNewButton=1&ShowPropButton=1//&DefaultType=1071';

Uncomment out this section and comment out the section:

    //On-premise
    var url = '/' + Xrm.Page.context.getOrgUniqueName() +
      '/_controls/lookup/lookupsingle.aspx?class=BrowseCustomerAddress&objecttypes=1071&browse=1&bindingcolumns=line1%2cpostalcode&parentType='
        + lookupItem[0].type + '&parentId='
        + lookupItem[0].id + '&ShowNewButton=1&ShowPropButton=1&DefaultType=1071';

If you would like to deploy this solution to a CRM On-line environment.

Finally, save and publish the solution and create a new contact.  There you have it, your address lookup button!  Simply click it and it will pull through one of the addresses related to the parent customer of the contact record.
on Wednesday, 10 April 2013


Get the Value from a CRM Field
var varMyValue = Xrm.Page.getAttribute("CRMFieldSchemaName").getValue() ;
Set the Value of a CRM Field
Xrm.Page.getAttribute("CRMFieldSchemaName").setValue('My New Value');
Hide/Show Tab
Xrm.Page.ui.tabs.get(5).setVisible(false);
Xrm.Page.ui.tabs.get(5).setVisible(true);
Hide/Show Section
Xrm.Page.ui.tabs.get(5).sections.get(0).setVisible(false);
Xrm.Page.ui.tabs.get(5).sections.get(0).setVisible(true);
Call the On-Change Event of a Field
Xrm.Page.getAttribute("CRMFieldSchemaName").fireOnChange();
Get the Selected Value of a Pick-List
Xrm.Page.getAttribute("CRMFieldSchemaName").getSelectedOption().text;
Set Field Requirement Level
Xrm.Page.getAttribute("CRMFieldSchemaName").setRequiredLevel("none");
Xrm.Page.getAttribute("CRMFieldSchemaName").setRequiredLevel("required");
Xrm.Page.getAttribute("CRMFieldSchemaName").setRequiredLevel("recommended");
Set the Focus to a Field
Xrm.Page.getControl("CRMFieldSchemaName").setFocus(true);
Stop an On-Save Event
event.returnValue = false;
executionObj.getEventArgs().preventDefault();
Return Array of Strings Consisting of User Security Role GUIDs
Xrm.Page.context.getUserRoles();
Get Record GUID
var recordId = Xrm.Page.data.entity.getId();
var recordIdWithoutCurlyBraces = Xrm.Page.data.entity.getId().substring(1,37);
Get Event Source
var eventSource = executionContext.getEventSource();
Get Event Source (Field Name)
var fieldName = executionContext.getEventSource().getName();
Get Event Source (Value)
var fieldValue= executionContext.getEventSource().getValue();

Set Lookup Value
Xrm.Page.getAttribute('new_fieldid').setValue([{ id: 'guid', name: fullName, entityType: 'entityTypeName'}]);
Disable/Enable Field
Xrm.Page.getControl(fieldName).setDisabled(true);
Xrm.Page.getControl(fieldName).setDisabled(false);
Hide/Show Field
Xrm.Page.ui.controls.get(fieldName).setVisible(false);
Xrm.Page.ui.controls.get(fieldName).setVisible(true);
Get Form Type
var FORM_TYPE_CREATE = 1;
var FORM_TYPE_UPDATE = 2;
var FORM_TYPE_READ_ONLY = 3;
var FORM_TYPE_DISABLED = 4;
var FORM_TYPE_QUICK_CREATE = 5;
var FORM_TYPE_BULK_EDIT = 6;
var formType = Xrm.Page.ui.getFormType();
if (formType == FORM_TYPE_CREATE) {
}
else {
}
Modify Field Label Tooltip
document.getElementById("field_name_c").setAttribute("title", "tooltip text");

Modify Lookup Button Tooltip
document.getElementById("field_name").setAttribute("title", "tooltip text");

Call a field's On-Change Event
Xrm.Page.getAttribute("field_name").fireOnChange();