Tag Archives: jscript

Duplicate Record Button using Jscript in Microsoft CRM 2011

As detailed here, Rollup Pack 8 for Microsoft CRM 2011 gave us a couple of shiny new jscript toys:

Xrm.Utility.openEntityForm(name,id,parameters)

and

Xrm.Utility.openWebResource(webResourceName,webResourceData,width, height)

In this post I will show you how to add a “Duplicate Record” button to a CRM form, using the new openEntityForm function.

First, lets add the button.  Download Erik Pool’s ribbon editor from CodePlex.  If you are still editing ribbon xml manually and not using this tool then you are mad.   Run the tool, connect to your CRM organisation and open the ribbon you wish to edit.  I am going to add my button to the Case form, adding to the last Group of buttons on the right hand side.  I click in that Button Group and then click New Button and name my button:

image

My button appears small by default so I change the Template Alias to Large.  I need an icon for my button and the one I see on the “Copy Selected” button looks good so I can click on that button and copy and paste the image properties from that button over to my new button:

image

I tidy the Label and Tooltip and then click on the Action tab and enter the name of my jscript library and function, which we will create next:

image

Finally, I save the change and then check my button appears in CRM:

image

I want to demonstrate copying a range of data types so I add a few custom fields to my Case form:

image

Ok, now we can write the jscript function.  There are 3 steps to this:

1. Collect field values from the source record

2. Define the values you want to populate into the destination record

3. Pop the form, passing across the values to be populated

I’ve pasted just the first part below.  Most of this is just me using CRM’s getValue() functon, but you will see I do some null value checks on the lookup fields (to avoid errors) and I also need to extract multiple values from each lookup field.  You will also note for the date field I call another function so that the value returned by the getValue() call gets converted into the MM/DD/YYYY format that the next step requires:

function DuplicateCase() {
    //get values from the Form
    var CaseId = Xrm.Page.data.entity.getId();
    var CaseTitle = Xrm.Page.data.entity.attributes.get("title").getValue();
    if (Xrm.Page.data.entity.attributes.get("customerid").getValue() != null) {
        var CustomerId = Xrm.Page.data.entity.attributes.get("customerid").getValue()[0].id;
        var CustomerName = Xrm.Page.data.entity.attributes.get("customerid").getValue()[0].name;
        var CustomerType = Xrm.Page.data.entity.attributes.get("customerid").getValue()[0].entityType;
    }
    if (Xrm.Page.data.entity.attributes.get("subjectid").getValue() != null) {
        var SubjectId = Xrm.Page.data.entity.attributes.get("subjectid").getValue()[0].id;
        var SubjectName = Xrm.Page.data.entity.attributes.get("subjectid").getValue()[0].name;
    }
    var CaseOriginCode = Xrm.Page.data.entity.attributes.get("caseorigincode").getValue();
    var CaseTypeCode = Xrm.Page.data.entity.attributes.get("casetypecode").getValue();
    var CaseDate = FormatDate("new_dateofincident");  // wants "MM/DD/YYYY" (this might be environment specific though)
    var CaseUrgent = Xrm.Page.data.entity.attributes.get("new_urgent").getValue();
    var CaseClaimAmount = Xrm.Page.data.entity.attributes.get("new_claimamount").getValue();
    if (Xrm.Page.data.entity.attributes.get("transactioncurrencyid").getValue() != null) {
        var CurrencyId = Xrm.Page.data.entity.attributes.get("transactioncurrencyid").getValue()[0].id;
        var CurrencyName = Xrm.Page.data.entity.attributes.get("transactioncurrencyid").getValue()[0].name;
    }
    if (Xrm.Page.data.entity.attributes.get("ownerid").getValue() != null) {
        var OwnerId = Xrm.Page.data.entity.attributes.get("ownerid").getValue()[0].id;
        var OwnerName = Xrm.Page.data.entity.attributes.get("ownerid").getValue()[0].name;
        var OwnerType = Xrm.Page.data.entity.attributes.get("ownerid").getValue()[0].entityType;
    }
    var CaseDescription = Xrm.Page.data.entity.attributes.get("description").getValue();

Here’s the second section of the function, here I am basically placing each of the values I extracted during step 1 into a parameter object (testing for and excluding null values as I go):

 

    //define default values for new Incident record
    var parameters = {};
    if (CaseTitle != null) {
        parameters["title"] = CaseTitle + " - COPY";
    }
    if (CustomerId != null && CustomerName != null) {
        parameters["customerid"] = CustomerId;
        parameters["customeridname"] = CustomerName;
        parameters["customeridtype"] = CustomerType;
    }
    if (SubjectId != null && SubjectName != null) {
        parameters["subjectid"] = SubjectId;
        parameters["subjectidname"] = SubjectName;
    }
    if (CaseOriginCode != null) {
        parameters["caseorigincode"] = CaseOriginCode;
    }
    if (CaseTypeCode != null) {
        parameters["casetypecode"] = CaseTypeCode;
    }
    if (CaseDate != null) {
        parameters["new_dateofincident"] = CaseDate;
    }
    if (CaseUrgent != null) {
        parameters["new_urgent"] = CaseUrgent;
    }
    if (CaseClaimAmount != null) {
        parameters["new_claimamount"] = CaseClaimAmount;
    }
    if (CurrencyId != null && CurrencyName != null) {
        parameters["transactioncurrencyid"] = CurrencyId;
        parameters["transactioncurrencyidname"] = CurrencyName;
    }
    if (OwnerId != null && OwnerName != null) {
        parameters["ownerid"] = OwnerId;
        parameters["owneridname"] = OwnerName;
        parameters["owneridtype"] = OwnerType;
    }
    if (CaseDescription != null) {
        parameters["description"] = CaseDescription;
    }
    if (CaseId != null && CaseTitle != null) {
        parameters["new_parentcase"] = CaseId;
        parameters["new_parentcasename"] = CaseTitle;
    }

And the last bit is simply:

    //pop incident form with default values
    Xrm.Utility.openEntityForm("incident", null, parameters);
}

Here’s how it looks in action.  Here’s my source record:

image

And here’s what pops up when I click the button:

image

To use this yourself in your unique scenarios you will obviously need to edit the getValue() and parameters lines to match your fields.  I’ve covered off the main data types and added a little bit of robustness to help guide you on this.   The openEntityForm utility certainly helps out here.

Here’s the jscript function in full and the missing FormatDate function:

function DuplicateCase() {
    //get values from the Form
    var CaseId = Xrm.Page.data.entity.getId();
    var CaseTitle = Xrm.Page.data.entity.attributes.get("title").getValue();
    if (Xrm.Page.data.entity.attributes.get("customerid").getValue() != null) {
        var CustomerId = Xrm.Page.data.entity.attributes.get("customerid").getValue()[0].id;
        var CustomerName = Xrm.Page.data.entity.attributes.get("customerid").getValue()[0].name;
        var CustomerType = Xrm.Page.data.entity.attributes.get("customerid").getValue()[0].entityType;
    }
    if (Xrm.Page.data.entity.attributes.get("subjectid").getValue() != null) {
        var SubjectId = Xrm.Page.data.entity.attributes.get("subjectid").getValue()[0].id;
        var SubjectName = Xrm.Page.data.entity.attributes.get("subjectid").getValue()[0].name;
    }
    var CaseOriginCode = Xrm.Page.data.entity.attributes.get("caseorigincode").getValue();
    var CaseTypeCode = Xrm.Page.data.entity.attributes.get("casetypecode").getValue();
    var CaseDate = FormatDate("new_dateofincident");  // wants "MM/DD/YYYY" (this might be environment specific though)
    var CaseUrgent = Xrm.Page.data.entity.attributes.get("new_urgent").getValue();
    var CaseClaimAmount = Xrm.Page.data.entity.attributes.get("new_claimamount").getValue();
    if (Xrm.Page.data.entity.attributes.get("transactioncurrencyid").getValue() != null) {
        var CurrencyId = Xrm.Page.data.entity.attributes.get("transactioncurrencyid").getValue()[0].id;
        var CurrencyName = Xrm.Page.data.entity.attributes.get("transactioncurrencyid").getValue()[0].name;
    }
    if (Xrm.Page.data.entity.attributes.get("ownerid").getValue() != null) {
        var OwnerId = Xrm.Page.data.entity.attributes.get("ownerid").getValue()[0].id;
        var OwnerName = Xrm.Page.data.entity.attributes.get("ownerid").getValue()[0].name;
        var OwnerType = Xrm.Page.data.entity.attributes.get("ownerid").getValue()[0].entityType;
    }
    var CaseDescription = Xrm.Page.data.entity.attributes.get("description").getValue();

    //define default values for new Incident record
    var parameters = {};
    if (CaseTitle != null) {
        parameters["title"] = CaseTitle + " - COPY";
    }
    if (CustomerId != null && CustomerName != null) {
        parameters["customerid"] = CustomerId;
        parameters["customeridname"] = CustomerName;
        parameters["customeridtype"] = CustomerType;
    }
    if (SubjectId != null && SubjectName != null) {
        parameters["subjectid"] = SubjectId;
        parameters["subjectidname"] = SubjectName;
    }
    if (CaseOriginCode != null) {
        parameters["caseorigincode"] = CaseOriginCode;
    }
    if (CaseTypeCode != null) {
        parameters["casetypecode"] = CaseTypeCode;
    }
    if (CaseDate != null) {
        parameters["new_dateofincident"] = CaseDate;
    }
    if (CaseUrgent != null) {
        parameters["new_urgent"] = CaseUrgent;
    }
    if (CaseClaimAmount != null) {
        parameters["new_claimamount"] = CaseClaimAmount;
    }
    if (CurrencyId != null && CurrencyName != null) {
        parameters["transactioncurrencyid"] = CurrencyId;
        parameters["transactioncurrencyidname"] = CurrencyName;
    }
    if (OwnerId != null && OwnerName != null) {
        parameters["ownerid"] = OwnerId;
        parameters["owneridname"] = OwnerName;
        parameters["owneridtype"] = OwnerType;
    }
    if (CaseDescription != null) {
        parameters["description"] = CaseDescription;
    }
    if (CaseId != null && CaseTitle != null) {
        parameters["new_parentcase"] = CaseId;
        parameters["new_parentcasename"] = CaseTitle;
    }

    //pop incident form with default values
    Xrm.Utility.openEntityForm("incident", null, parameters);
}

// This function takes the fieldname of a date field as input and returns the value of that field in MM/DD/YYYY format
// Note: the day, month and year variables are numbers
function FormatDate(fieldname) {
    var d = Xrm.Page.data.entity.attributes.get(fieldname).getValue();  
    if (d != null) {
        var curr_date = d.getDate();
        var curr_month = d.getMonth();
        curr_month++;  // getMonth() considers Jan month 0, need to add 1
        var curr_year = d.getFullYear();
        return curr_month + "/" + curr_date + "/" + curr_year;
    }
    else return null;
}
Advertisements

Reusable Jscript Library of Common Functions for CRM 2011

I find myself needing the same jscript over and over again when I build out demos.  To make life easier I decided to create a function library that I can attach to any CRM form.  Here it is.  I will add to this over time. 

If you have any useful functions that should be included post them in the comments and I’ll incorporate them.  The jscript is available here and below.   At the end of this post you will see some examples demonstrating the use of these functions.

Warning: these functions are of a ‘demo’ standard, and should be hardened and tested before used in a production setting.

p.s. my older jscript reference post has been updated recently as well, check it out.

// Determine Form Type
// example: GetFormType();
function GetFormType() {
    var FormType = Xrm.Page.ui.getFormType();
    if (FormType != null) {
        switch (FormType) {
            case 1:
                return "create";
                break;
            case 2:
                return "update";
                break;
            case 3:
                return "readonly";
                break;
            case 4:
                return "disabled";
                break;
            case 6:
                return "bulkedit";
                break;
            default:
                return null;
        }
    }
}

// Show/Hide a TAB
// example: HideShowTab("General", false);   // "false" = invisible
function HideShowTab(tabName, visible) {
    try {
        Xrm.Page.ui.tabs.get(tabName).setVisible(visible);
    }
    catch (err) { }
}

// Show/Hide a SECTION
// example: HideShowSection("General", "Customers", false);   // "false" = invisible
function HideShowSection(tabName, sectionName, visible) {
    try {
        Xrm.Page.ui.tabs.get(tabName).sections.get(sectionName).setVisible(visible);
    }
    catch (err) { }
}

// Get GUID value of Lookup Field
// example GetGUIDofLookup("primarycontactid");
function GetGUIDofLookup(fieldname) {
    if (Xrm.Page.data.entity.attributes.get(fieldname).getValue() != null) {
        return Xrm.Page.data.entity.attributes.get(fieldname).getValue()[0].id;
    }
    else return null;
}

// Get Name value of Lookup Field
// example GetNameofLookup("primarycontactid");
function GetNameofLookup(fieldname) {
    if (Xrm.Page.data.entity.attributes.get(fieldname).getValue() != null) {
        return Xrm.Page.data.entity.attributes.get(fieldname).getValue()[0].name;
    }
    else return null;
}

// Get Value of Text Field
// example GetTextField("telephone1");
function GetTextField(fieldname) {
    return Xrm.Page.data.entity.attributes.get(fieldname).getValue();
}

// Get Integer value of Option Set Field
// example GetOptionsetInteger("address1_addresstypecode");
function GetOptionsetInteger(fieldname) {
    return Xrm.Page.data.entity.attributes.get(fieldname).getValue();
}

// Get Text value of Option Set Field
// example GetOptionsetText("address1_addresstypecode");
function GetOptionsetText(fieldname) {
    if (Xrm.Page.data.entity.attributes.get(fieldname).getValue() != null) {
        return Xrm.Page.data.entity.attributes.get(fieldname).getSelectedOption().text;
    }
    else return null;
}

// Get Database Value of a Bit Field
// example GetBitValue("telephone1");
function GetBitValue(fieldname) {
    return Xrm.Page.data.entity.attributes.get(fieldname).getValue();
}

// Get Database Value of a Date Field
// example GetDate("createdon");
function GetDate(fieldname) {
    return Xrm.Page.data.entity.attributes.get(fieldname).getValue();
}

// Sets the time portion of a date field (and sets the date to today if blank)
// Example: SetTime('new_date2', 8, 30);
function SetTime(attributeName, hour, minute) {
        var attribute = Xrm.Page.getAttribute(attributeName);
        if (attribute.getValue() == null) {
            attribute.setValue(new Date());
        }
        attribute.setValue(attribute.getValue().setHours(hour, minute, 0));
}

// Converts a CRM date value into dd-mm-yyyy
// Example:     
//              var ReviewDate = Xrm.Page.data.entity.attributes.get(new_date2).getValue(); 
//              alert(FormatDate(ReviewDate));
function FormatDate(fieldname) {
    var d = Xrm.Page.data.entity.attributes.get(fieldname).getValue();
    if (d != null) {
        var curr_date = d.getDate();
        var curr_month = d.getMonth();
        curr_month++;  // getMonth() considers Jan month 0, need to add 1
        var curr_year = d.getFullYear();
        return curr_date + "-" + curr_month + "-" + curr_year;
    }
    else return null;
}

// Compares a date to today's date
// Example:     
//              var ReviewDate = Xrm.Page.data.entity.attributes.get(new_date2).getValue(); 
//              alert(DateCompare(ReviewDate));
// Returns:  "future date", "date is in the past", or "date is today"
function DateCompare(dateinput) {
    var today = new Date();
    var today_date = today.getDate();
    var today_month = today.getMonth();
    today_month++;
    var today_year = today.getFullYear();

    var dateinput_date = dateinput.getDate();
    var dateinput_month = dateinput.getMonth();
    dateinput_month++;
    var dateinput_year = dateinput.getFullYear();

    if (dateinput != null && dateinput_year > today_year) {  // future year
        return "future date";
    }
    else if (dateinput != null && dateinput_year < today_year) {  // prior year
        return "date is in the past";
    }
    else if (dateinput != null && dateinput_year == today_year && dateinput_month > today_month) { //current year, future month
        return "future date";
    }
    else if (dateinput != null && dateinput_year == today_year && dateinput_month < today_month) { //current year, prior month
        return "date is in the past";
    }
    else if (dateinput != null && dateinput_year == today_year && dateinput_month == today_month && dateinput_date > today_date) { //current year, current month, future date
        return "future date";
    }
    else if (dateinput != null && dateinput_year == today_year && dateinput_month == today_month && dateinput_date < today_date) { //current year, current month, prior date
        return "date is in the past";
    }
    else if (dateinput != null && dateinput_year == today_year && dateinput_month == today_month && dateinput_date == today_date) { //same date
        return "date is today";
    }
    else {
        return null;
    }
}

/////////////////////////////////////////////////////////////////////////////
// Here's a few more courtesy of Paul Kreeck
/////////////////////////////////////////////////////////////////////////////
///Gets the Attributes by its Name.
 GetAttributeByName: function (attributeName)
 {
 return Xrm.Page.getAttribute(attributeName);
 } 

///Sets the attributes required level.
 ///
 ///Values: ‘none’, ‘required’, ‘recommended’
SetAttributeRequiredLevel: function (attributeName, level)
 {
 var attribute = GetAttributeByName(attributeName);
 if (attribute != null)
 {
 return attribute.setRequiredLevel(level);
 }
 return null;
 }
 
///Sets whether data from the attribute will be submitted when the record is saved.
 ///
 ///Values: ‘always’, ‘never’, ‘dirty’
SetAttributeSubmitMode: function (attributeName, submitMode)
 {
 var attribute = GetAttributeByName(attributeName);
 
if (attribute != null)
 {
 if (submitMode == “always” || submitMode == “never” || submitMode == “dirty”)
 {
attribute.setSubmitMode(submitMode);
 }
 else
 {
 throw “Invalid Submit Mode parameter”;
 }
 }
 }

 

Here are some examples where I utilise the above functions:

function AccountFormOnLoad() {
    var FormType = GetFormType();
    alert("Form type: " + FormType);

    alert(GetDate("createdon"));
    alert(FormatDate("createdon"));

    SetTime('new_date2', 8, 30);

    var FieldDate = GetDate("new_date2");
    alert(DateCompare(FieldDate));
    
    if(FormType == "update") {
        alert("hiding General tab");
        HideShowTab("general", false);

        alert("UNhiding General tab");
        HideShowTab("general", true);

        alert("hiding address section on general tab");
        HideShowSection("general", "address", false);

        alert("UNhiding address section on general tab");
        HideShowSection("general", "address", true);

        alert("getting GUID of primary contact");
        alert(GetGUIDofLookup("primarycontactid"));

        alert("getting name of primary contact");
        alert(GetNameofLookup("primarycontactid"));

        alert("getting value of telephone1");
        alert(GetTextField("telephone1"));

        alert("getting integer value of address type");
        alert(GetOptionsetInteger("address1_addresstypecode"));

        alert("getting text value of address type");
        alert(GetOptionsetText("address1_addresstypecode"));
    }
}

 

To reference the jscript library on a CRM form add the shared function library web resource to the Form and then add a form-specific jscript library web resource after that.  It is in this second jscript file that your form logic will sit and where you will make function calls against the shared functions library:

image

 

To reference the jscript library within a  custom Ribbon button’s definition either;

simply reference the library on the form:

image

or, you can reference the library within the ribbon definition:

        <CommandDefinitions>
          <CommandDefinition Id="ActivityFeeds.Form.account.MainTab.ExportData.Test.Command">
            <EnableRules />
            <DisplayRules />
            <Actions>
				<JavaScriptFunction Library="$WebResource:new_shared_functions.js" FunctionName="NaN" />
				<JavaScriptFunction Library="$WebResource:new_account_form_examples.js" FunctionName="AccountFormOnLoad" />
            </Actions>
          </CommandDefinition>
        </CommandDefinitions>

 

Note: you have to specify a Function name when you reference a jscript library so just use some dummy value like “NaN”

Supporting Environment-specific Parameters in CRM 2011 Jscript

In this post I present an approach for managing environment-specific variables that you might use in your CRM 2011 jscript functions.  Imagine you have developed some jscript code that needs environment specific values such as the GUID of a specific view, workflow or dialog.  Here’s my approach using a custom entity and REST…

Here’s a scenario to provide some context.  In this post Rhett Clinton provides a jscript solution for defaulting a Customer Lookup to Contact rather than Account.

i.e. when you click on the Phone Call form’s “Sender” field the lookup that appears has “Look for” set to Contact rather than Account:

image

The line of code that does this is highlighted below:

image

The second line above is there to overcome a problem.  Without that 2nd line what you find is the lookup window switches to Contact but the default view in the lookup defers to whatever the default public view for the entity is – for Contact this is typically “My Active Contacts” – and this isn’t typically what we want.  

The second line of code changes the default view to “All Actives Contact” but a hardcoded value is being used.  Here’s how we can avoid this hardcoding…


Firstly, the best place for this configuration data is in a CRM entity record.  It’s an easy data store for us to query, it is fully securable and if required we can leverage CRM’s audit, field level security, and data import functionality.  Here’s my entity:

image

I have implemented a simple data model.  A record consists of an identifying name and then the configuration value.  The Value field is a multi-line text field which means it can support a simple single text field or numeric value or a more complicated XML value.

To query for this GUID from the Phone Call form I need to use a REST query.  Now, because REST uses asynchronous ajax calls we have to have be careful here and I need to split my jscript across 3 functions.  The first function is executed onload and switches the Customer lookup to default to the Contact entity.  It then calls function #2 which performs the REST query and queries for my environment-specific parameter value.  Function #3 contains the stuff that I want to happen once I have that parameter value, and it is called on success of the ajax query inside function 2.  I had to put this last bit of code into a seperate function and not just have it follow on in function 1 due to asynchronous timing issues.  Here are the 3 functions:

function OnLoad() {
    document.getElementById("from").setAttribute("defaulttype", "2");
    GetConfigValue("ActiveContactsViewGUID");
}

function GetConfigValue(ConfigParamName) {
    // Get the CRM URL 
    var serverUrl = Xrm.Page.context.getServerUrl();

    // Cater for URL differences between on premise and online 
    if (serverUrl.match(/\/$/)) {
        serverUrl = serverUrl.substring(0, serverUrl.length - 1);
    }

    // Specify the ODATA end point (this is the same for all CRM 2011 implementations) 
    var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";

    // Specify the ODATA entity collection (this needs to be specific to your entity) 
    var ODATA_EntityCollection = "/new_configurationSet";

    // Specify the ODATA filter 
    var ODATA_Query = "?$select=new_Value&$filter=new_name%20eq%20\'" + ConfigParamName + "\'&$top=1";

    // Build the URL 
    var ODATA_Final_url = serverUrl + ODATA_ENDPOINT + ODATA_EntityCollection + ODATA_Query;

    //Call the REST endpoint 
    $.ajax({
        type: "GET",
        contentType: "application/json; charset=utf-8",
        datatype: "json",
        url: ODATA_Final_url,
        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) {
            //This function will trigger asynchronously if the Retrieve was successful 
            ChangeView(data.d.results[0].new_Value);
        },
        error: function (XmlHttpRequest, textStatus, errorThrown) {
            //This function will trigger asynchronously if the Retrieve returned an error 
            alert("ajax call failed");
        }
    });
}

function ChangeView(ConfigValue) {
    Xrm.Page.getControl("from").setDefaultView(ConfigValue);
}

Now because we are using REST we need to add references to web resources containing  json and jquery libraries (more details here):

image 


So, that’s the approach.  Now how do you apply this when you need it?  Simple.

  1. Whenever you have this need, Import this solution file to add the Configuration entity and jquery and json web resources to your system.
  2. Publish All Customisations.
  3. Create a Configuration record in the new Configuration entity, assign the environment variable a Name and then store the Value.   In each environment, this record needs to exist with the same Name, but obviously the Value will be environment specific.
  4. Add References to the jquery and json web resources on your CRM form.
  5. Add to your form script the GetConfigValue() function I have provided above.
  6. In your script call the GetConfigValue() function passing in the Name of the environment variable you wish to retrieve.  Warning: do not have any jscript below this point in this function.  Any subsequent jscript needs to go in  the function described below.
  7. Modify line 39 of the GetConfigValue() function and swap out “ChangeView” with the name of your function which contains the actions that need to execute once the environment parameter has been obtained. 

JavaScript Reference for Microsoft Dynamics CRM 2011 / 2013

Here’s a quick reference guide covering Microsoft CRM syntax for common jscript requirements.

Most of the examples are provided as functions that you can easily test in the OnLoad event of the Account form to see a working example.  These are not production hardened but they’ll help you with the CRM syntax.

(updated: 30 July 2012)

Index:

  1.   Get the GUID value of a Lookup field
  2.   Get the Text value of a Lookup field
  3.   Get the value of a Text field
  4.   Get the database value of an Option Set field
  5.   Get the text value of an Option Set field
  6.   Get the database value of a Bit field
  7.   Get the value of a Date field
  8.   Get the day, month and year parts from a Date field
  9.   Set the value of a String field
  10. Set the value of an Option Set (pick list) field
  11. Set a Date field / Default a Date field to Today
  12. Set a Date field to 7 days from now
  13. Set the Time portion of a Date Field
  14. Set the value of a Lookup field
  15. Split a Full Name into First Name and Last Name fields
  16. Set the Requirement Level of a Field
  17. Disable a field
  18. Force Submit the Save of a Disabled Field
  19. Show/Hide a Field
  20. Show/Hide a field based on a Bit field
  21. Show/Hide a Nav item
  22. Show/Hide a Section
  23. Show/Hide a Tab
  24. Save the form
  25. Save and close the form
  26. Close the form
  27. Determine which fields on the form are dirty
  28. Determine the Form Type
  29. Get the GUID of the current record
  30. Get the GUID of the current user
  31. Get the Security Roles of the current user
  32. Determine the CRM Server URL
  33. Refresh a Sub-Grid
  34. Change the default entity in the lookup window of a Customer or Regarding field
  35. Pop an existing CRM record (new approach)
  36. Pop an existing CRM record (old approach)
  37. Pop a blank CRM form (new approach)
  38. Pop a new CRM record with default values (new approach)
  39. Pop a new CRM record with default values (old approach)
  40. Pop a Dialog from a ribbon button
  41. Pop a URL from a ribbon button
  42. Pop the lookup window associated to a Lookup field
  43. Pop a Web Resource (new approach)
  44. SWITCH statements
  45. Pop an Ok/Cancel dialog
  46. Retrieve a GUID via REST (default the Price List field)

1.  Get the GUID value of a lookup field:

Note: this example reads and pops the GUID of the primary contact on the Account form

function AlertGUID() {
    var primaryContactGUID = Xrm.Page.data.entity.attributes.get("primarycontactid").getValue()[0].id;
    alert(primaryContactGUID);
}

2.  Get the Text value of a lookup field:

Note: this example reads and pops the name of the primary contact on the Account form

function AlertText() {
    var primaryContactName = Xrm.Page.data.entity.attributes.get("primarycontactid").getValue()[0].name;
    alert(primaryContactName);
}

3.  Get the value of a text field:

Note: this example reads and pops the value of the Main Phone (telephone1) field on the Account form

function AlertTextField() {
    var MainPhone = Xrm.Page.data.entity.attributes.get("telephone1").getValue();
    alert(MainPhone);
}

4.  Get the database value of an Option Set field:

Note: this example reads and pops the value of the Address Type (address1_addresstypecode) field on the Account form

function AlertOptionSetDatabaseValue() {
    var AddressTypeDBValue = Xrm.Page.data.entity.attributes.get("address1_addresstypecode").getValue();
    if (AddressTypeDBValue != null) {
        alert(AddressTypeDBValue);
    }
}

5.  Get the text value of an Option Set field:

Note: this example reads and pops the value of the Address Type (address1_addresstypecode) field on the Account form

function AlertOptionSetDisplayValue() {
   var AddressTypeDisplayValue = Xrm.Page.data.entity.attributes.get("address1_addresstypecode").getText();
    if (AddressTypeDisplayValue != null) {
        alert(AddressTypeDisplayValue);
    }
}

6.  Get the database value of a Bit field:

// example GetBitValue("telephone1");
function GetBitValue(fieldname) {
    return Xrm.Page.data.entity.attributes.get(fieldname).getValue();
}

7.  Get the value of a Date field:

returns a value like: Wed Nov 30 17:04:06 UTC+0800 2011

and reflects the users time zone set under personal options

// example GetDate("createdon");
function GetDate(fieldname) {
    return Xrm.Page.data.entity.attributes.get(fieldname).getValue();
}

8.  Get the day, month and year parts from a Date field:

// This function takes the fieldname of a date field as input and returns a DD-MM-YYYY value
// Note: the day, month and year variables are numbers
function FormatDate(fieldname) {
    var d = Xrm.Page.data.entity.attributes.get(fieldname).getValue();
    if (d != null) {
        var curr_date = d.getDate();
        var curr_month = d.getMonth();
        curr_month++;  // getMonth() considers Jan month 0, need to add 1
        var curr_year = d.getFullYear();
        return curr_date + "-" + curr_month + "-" + curr_year;
    }
    else return null;
}

// An example where the above function is called
alert(FormatDate("new_date2"));

9.  Set the value of a string field:

Note: this example sets the Account Name field on the Account Form to “ABC”

function SetStringField() {
    var Name = Xrm.Page.data.entity.attributes.get("name");
    Name.setValue("ABC");
}

10.  Set the value of an Option Set (pick list) field:

Note: this example sets the Address Type field on the Account Form to “Bill To”, which corresponds to a database value of “1”

function SetOptionSetField() {
    var AddressType = Xrm.Page.data.entity.attributes.get("address1_addresstypecode");
    AddressType.setValue(1);
}

11.  Set a Date field / Default a Date field to Today:

//set date field to now (works on date and date time fields)
Xrm.Page.data.entity.attributes.get("new_date1").setValue(new Date());

12.  Set a Date field to 7 days from now:

function SetDateField() {
    var today = new Date();
    var futureDate = new Date(today.setDate(today.getDate() + 7));
    Xrm.Page.data.entity.attributes.get("new_date2").setValue(futureDate);
    Xrm.Page.data.entity.attributes.get("new_date2").setSubmitMode("always"); // Save the Disabled Field
}

13.  Set the Time portion of a Date Field:

// This is a function you can call to set the time portion of a date field
function SetTime(attributeName, hour, minute) {
        var attribute = Xrm.Page.getAttribute(attributeName);
        if (attribute.getValue() == null) {
            attribute.setValue(new Date());
        }
        attribute.setValue(attribute.getValue().setHours(hour, minute, 0));
}

// Here's an example where I use the function to default the time to 8:30am
SetTime('new_date2', 8, 30);

14.  Set the value of a Lookup field:

Note: here I am providing a reusable function…

// Set the value of a lookup field
function SetLookupValue(fieldName, id, name, entityType) {
    if (fieldName != null) {
        var lookupValue = new Array();
        lookupValue[0] = new Object();
        lookupValue[0].id = id;
        lookupValue[0].name = name;
        lookupValue[0].entityType = entityType;
        Xrm.Page.getAttribute(fieldName).setValue(lookupValue);
    }
}

Here’s an example of how to call the function (I retrieve the details of one lookup field and then call the above function to populate another lookup field):

var ExistingCase = Xrm.Page.data.entity.attributes.get("new_existingcase");
if (ExistingCase.getValue() != null) {
    var ExistingCaseGUID = ExistingCase.getValue()[0].id;
    var ExistingCaseName = ExistingCase.getValue()[0].name;
    SetLookupValue("regardingobjectid", ExistingCaseGUID, ExistingCaseName, "incident");
}

15.  Split a Full Name into First Name and Last Name fields:

function PopulateNameFields() {
    var ContactName = Xrm.Page.data.entity.attributes.get("customerid").getValue()[0].name;
    var mySplitResult = ContactName.split(" ");
    var fName = mySplitResult[0];
    var lName = mySplitResult[1];
    Xrm.Page.data.entity.attributes.get("firstname").setValue(fName);
    Xrm.Page.data.entity.attributes.get("lastname").setValue(lName);
}

16.  Set the Requirement Level of a Field:

Note: this example sets the requirement level of the Address Type field on the Account form to Required. 

Note: setRequiredLevel(“none”) would make the field optional again.

function SetRequirementLevel() {
    var AddressType = Xrm.Page.data.entity.attributes.get("address1_addresstypecode");
    AddressType.setRequiredLevel("required");
}

17.  Disable a field:

function SetEnabledState() {
    var AddressType = Xrm.Page.ui.controls.get("address1_addresstypecode");
    AddressType.setDisabled(true);
}

18.  Force Submit the Save of a Disabled Field:

// Save the Disabled Field
Xrm.Page.data.entity.attributes.get("new_date1").setSubmitMode("always");

19.  Show/Hide a field:

function hideName() {
    var name = Xrm.Page.ui.controls.get("name");
    name.setVisible(false);
}

20.  Show/Hide a field based on a Bit field

function DisableExistingCustomerLookup() {
   var ExistingCustomerBit = Xrm.Page.data.entity.attributes.get("new_existingcustomer").getValue();
    if (ExistingCustomerBit == false) {
       Xrm.Page.ui.controls.get("customerid").setVisible(false);
    }
    else {
       Xrm.Page.ui.controls.get("customerid").setVisible(true);
    }
}

21.  Show/Hide a nav item:

Note: you need to refer to the nav id of the link, use F12 developer tools in IE to determine this

function hideContacts() {
    var objNavItem = Xrm.Page.ui.navigation.items.get("navContacts");
    objNavItem.setVisible(false);
}

22.  Show/Hide a Section:

Note: Here I provide a function you can use.  Below the function is a sample.

function HideShowSection(tabName, sectionName, visible) {
    try {
        Xrm.Page.ui.tabs.get(tabName).sections.get(sectionName).setVisible(visible);
    }
    catch (err) { }
}

HideShowSection("general", "address", false);   // "false" = invisible

23.  Show/Hide a Tab:

Note: Here I provide a function you can use. Below the function is a sample.

function HideShowTab(tabName, visible) {
    try {
        Xrm.Page.ui.tabs.get(tabName).setVisible(visible);
    }
    catch (err) { }
}

HideShowTab("general", false);   // "false" = invisible

24.  Save the form:

function SaveAndClose() {
    Xrm.Page.data.entity.save();
}

25.  Save and close the form:

function SaveAndClose() {
    Xrm.Page.data.entity.save("saveandclose");
}

26.  Close the form:

Note: the user will be prompted for confirmation if unsaved changes exist

function Close() {
    Xrm.Page.ui.close();
}

27.  Determine which fields on the form are dirty:

var attributes = Xrm.Page.data.entity.attributes.get()
 for (var i in attributes)
 {
    var attribute = attributes[i];
    if (attribute.getIsDirty())
    {
      alert("attribute dirty: " + attribute.getName());
    }
 }

28.  Determine the Form Type:

Note: Form type codes: Create (1), Update (2), Read Only (3), Disabled (4), Bulk Edit (6)

function AlertFormType() {
    var FormType = Xrm.Page.ui.getFormType();
     if (FormType != null) {
        alert(FormType);
    }
}

29.  Get the GUID of the current record:

function AlertGUID() {
    var GUIDvalue = Xrm.Page.data.entity.getId();
    if (GUIDvalue != null) {
        alert(GUIDvalue);
    }
}

30.  Get the GUID of the current user:

function AlertGUIDofCurrentUser() {
    var UserGUID = Xrm.Page.context.getUserId();
     if (UserGUID != null) {
        alert(UserGUID);
    }
}

31.  Get the Security Roles of the current user:

(returns an array of GUIDs, note: my example reveals the first value in the array only)

function AlertRoles() {
    alert(Xrm.Page.context.getUserRoles());
}

32.  Determine the CRM server URL:

// Get the CRM URL
var serverUrl = Xrm.Page.context.getServerUrl();

// Cater for URL differences between on premise and online
if (serverUrl.match(/\/$/)) {
    serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}

33.  Refresh a Sub-Grid:

var targetgird = Xrm.Page.ui.controls.get("target_grid");
targetgird.refresh();

34.  Change the default entity in the lookup window of a Customer or Regarding field:

Note: I am setting the customerid field’s lookup window to offer Contacts (entityid 2) by default (rather than Accounts). I have also hardcoded the GUID of the default view I wish displayed in the lookup window.

function ChangeLookup() {
    document.getElementById("customerid").setAttribute("defaulttype", "2");
    var ViewGUID= "A2D479C5-53E3-4C69-ADDD-802327E67A0D";
    Xrm.Page.getControl("customerid").setDefaultView(ViewGUID);
}

35.  Pop an existing CRM record (new approach):

function PopContact() {
    //get PrimaryContact GUID
    var primaryContactGUID = Xrm.Page.data.entity.attributes.get("primarycontactid").getValue()[0].id;
    if (primaryContactGUID != null) {
        //open Contact form
        Xrm.Utility.openEntityForm("contact", primaryContactGUID)
    }
}

36.  Pop an existing CRM record (old approach):

Note: this example pops an existing Case record.  The GUID of the record has already been established and is stored in the variable IncidentId.

//Set features for how the window will appear
var features = "location=no,menubar=no,status=no,toolbar=no";

// Get the CRM URL
var serverUrl = Xrm.Page.context.getServerUrl();

// Cater for URL differences between on premise and online
if (serverUrl.match(/\/$/)) {
    serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}

window.open(serverUrl + "/main.aspx?etn=incident&pagetype=entityrecord&id=" + encodeURIComponent(IncidentId), "_blank", features, false);

37.  Pop a blank CRM form (new approach):

function PopNewCase() {
    Xrm.Utility.openEntityForm("incident")
}

38.  Pop a new CRM record with default values (new approach):

function CreateIncident() {
    //get Account GUID and Name
    var AccountGUID = Xrm.Page.data.entity.getId();
    var AccountName = Xrm.Page.data.entity.attributes.get("name").getValue();
    //define default values for new Incident record
    var parameters = {};
    parameters["title"] = "New customer support request";
    parameters["casetypecode"] = "3";
    parameters["customerid"] = AccountGUID;
    parameters["customeridname"] = AccountName;
    parameters["customeridtype"] = "account";
    //pop incident form with default values
    Xrm.Utility.openEntityForm("incident", null, parameters);
}

39.  Pop a new CRM record with default values (old approach):

Note: this example pops the Case form from the Phone Call form, defaulting the Case’s CustomerID based on the Phone Call’s SenderID and defaulting the Case Title to “New Case”

//Collect values from the existing CRM form that you want to default onto the new record
var CallerGUID = Xrm.Page.data.entity.attributes.get("from").getValue()[0].id;
var CallerName = Xrm.Page.data.entity.attributes.get("from").getValue()[0].name;

//Set the parameter values
var extraqs = "&title=New Case";
extraqs += "&customerid=" + CallerGUID;
extraqs += "&customeridname=" + CallerName;
extraqs += "&customeridtype=contact";

//Set features for how the window will appear
var features = "location=no,menubar=no,status=no,toolbar=no";

// Get the CRM URL
var serverUrl = Xrm.Page.context.getServerUrl();

// Cater for URL differences between on premise and online
if (serverUrl.match(/\/$/)) {
    serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}

//Pop the window
window.open(serverUrl + "/main.aspx?etn=incident&pagetype=entityrecord&extraqs=" + encodeURIComponent(extraqs), "_blank", features, false);

40.  Pop a Dialog from a ribbon button

Note: this example has the Dialog GUID and CRM Server URL hardcoded, which you should avoid.  A simple function is included which centres the Dialog when launched.

function LaunchDialog(sLeadID) {
    var DialogGUID = "128CEEDC-2763-4FA9-AB89-35BBB7D5517D";
    var serverUrl = "https://avanademarchdemo.crm5.dynamics.com/";
    serverUrl = serverUrl + "cs/dialog/rundialog.aspx?DialogId=" + "{" + DialogGUID + "}" + "&EntityName=lead&ObjectId=" + sLeadID;
    PopupCenter(serverUrl, "mywindow", 400, 400);
    window.location.reload(true);
}

function PopupCenter(pageURL, title, w, h) {
    var left = (screen.width / 2) - (w / 2);
    var top = (screen.height / 2) - (h / 2);
    var targetWin = window.showModalDialog(pageURL, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
}

41.  Pop a URL from a ribbon button

Great info on the window parameters you can set here:  http://javascript-array.com/scripts/window_open/

function LaunchSite() {
    // read URL from CRM field
    var SiteURL = Xrm.Page.data.entity.attributes.get("new_sharepointurl").getValue();
    // execute function to launch the URL
    LaunchFullScreen(SiteURL);
}

function LaunchFullScreen(url) {
 // set the window parameters
 params  = 'width='+screen.width;
 params += ', height='+screen.height;
 params += ', top=0, left=0';
 params += ', fullscreen=yes';
 params += ', resizable=yes';
 params += ', scrollbars=yes';
 params += ', location=yes';

 newwin=window.open(url,'windowname4', params);
 if (window.focus) {
     newwin.focus()
 }
 return false;
}

42.  Pop the lookup window associated to a Lookup field:

window.document.getElementById('new_existingcase').click();

43.  Pop a Web Resource (new approach):

function PopWebResource() {
    Xrm.Utility.openWebResource("new_Hello");
}

44. Using a SWITCH statement

function GetFormType() {
    var FormType = Xrm.Page.ui.getFormType();
    if (FormType != null) {
        switch (FormType) {
            case 1:
                return "create";
                break;
            case 2:
                return "update";
                break;
            case 3:
                return "readonly";
                break;
            case 4:
                return "disabled";
                break;
            case 6:
                return "bulkedit";
                break;
            default:
                return null;
        }
    }
}

45.  Pop an Ok/Cancel Dialog

function SetApproval() {
    if (confirm("Are you sure?")) {
        // Actions to perform when 'Ok' is selected:
        var Approval = Xrm.Page.data.entity.attributes.get("new_phaseapproval");
        Approval.setValue(1);
        alert("Approval has been granted - click Ok to update CRM");
        Xrm.Page.data.entity.save();
    }
    else {
        // Actions to perform when 'Cancel' is selected:
        alert("Action cancelled");
    }
}

46.  Retrieve a GUID via REST (default the Price List field)

In this example (intended for the Opportunity form’s Onload event) I execute a REST query to retrieve the GUID of the Price List named “Wholesale Price List”.  I then execute the DefaultPriceList function to default the Price List field.  As this uses REST your CRM form will need json2 and jquery libraries registered on the CRM form (I have these libraries in a solution file I import when needed):

image

function RetrieveGUID() {
    // Get CRM Context
    var context = Xrm.Page.context;
    var serverUrl = context.getServerUrl();
    // Cater for URL differences between on-premise and online
    if (serverUrl.match(/\/$/)) {
        serverUrl = serverUrl.substring(0, serverUrl.length - 1);
    }
    // Define ODATA query
    var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";
    var ODATA_EntityCollection = "/PriceLevelSet";
    var PriceListName = 'Wholesale Price List';
    var QUERY = "?$select=PriceLevelId&$filter=Name%20eq%20'" + PriceListName + "'&$top=1";
    var URL = serverUrl + ODATA_ENDPOINT + ODATA_EntityCollection + QUERY;
    //Asynchronous AJAX call
    $.ajax({
        type: "GET",
        contentType: "application/json; charset=utf-8",
        datatype: "json",
        url: URL,
        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) {
            //This function will trigger asynchronously if the Retrieve was successful
            var GUID_Retrieved = data.d.results[0].PriceLevelId;
            DefaultPriceList(GUID_Retrieved, PriceListName);
        },
        error: function (XmlHttpRequest, textStatus, errorThrown) {
            //This function will trigger asynchronously if the Retrieve returned an error
            alert("ajax call failed");
        }
    });
}

function DefaultPriceList(GUID, NAME){
        var lookupValue = new Array();
        lookupValue[0] = new Object();
        lookupValue[0].id = GUID;
        lookupValue[0].name = NAME;
        lookupValue[0].entityType = "pricelevel";
        Xrm.Page.getAttribute("pricelevelid").setValue(lookupValue);
}

Here is a little more info that will help you get your head around the general design of all this…

Depending upon what you want to do you will interact with one of the following:

Xrm.Page.data.entity.attributes – The data fields represented by fields on the form

Xrm.Page.ui.controls – The user interface controls on the form

Xrm.Page.ui.navigation.items – The navigation items on the form

Xrm.Utility – A container of helpful functions

When referring to fields or controls you must specify the name of the field and surround with quotes (and make sure you get the case right):

image

When referring to nav items you must specify the nav ID and surround it with quotes.  To determine the nav ID:

– open the CRM form in IE

– hit F12 to activate IE’s developer tools (if it doesn’t appear, check for it under Task Manager and maximise it from there)

– in the developer tools window click the arrow to activate the “Select element by click” mode

– on the CRM form click the nav item (the dev tools window will take you to HTML definition of that element)

image

– just above there you will see the nav ID specified, look for id=”nav<something>”

image

When setting properties to true/false do not surround the true/false value with quotes.

Typically there are 2 steps to interacting with fields.  First you get the field as an object.  Then you interact with that object to get or set the property value you are interested in.

Here’s an excellent post that provides a comparison of CRM v4 syntax and CRM 2011:

http://community.dynamics.com/product/crm/crmtechnical/b/crminogic/archive/2011/02/19/difference-between-crm-4-0-and-crm2011-script-for-using-on-form-customization.aspx

And here’s a download containing similar code snippets but provisioned as installable Visual Studio code snippets (something I wasn’t aware of but think is pretty cool!).

Here’s another useful jscript list:  http://andreaswijayablog.blogspot.com/2011/07/crm-2011-javascript-functions.html