Category Archives: Customization

Tips and Tricks for customizing Microsoft CRM 3.0

Two Steps to Becoming a betting Dynamics CRM JavaScript Developer

Happy Friday everyone.

I get asked all of the time about becoming a Dynamics CRM Developer or becoming a better one.

Here are two things you can do today, to start down that path:

1. Sign up for Visual Studio Team Services

Formerly Visual Studio Online.

It is free for up to 5 developers and you get all kinds of stuff in the mix:

Features included

All of your team members (OK, all except your free stakeholders) can use these features in your Visual Studio Team Services account:

Need more info? Check out our detailed feature matrix.

You simply cannot underestimate the power and necessity of having a source control system on your side, for ANY type of development you do. Even if you only use the Version Control component of Team Services, you are well ahead of the game. The other features are just developer productivity gravy.

2. Purchase XrmToolKit

Formerly the CRM Solution Manager. [Note: this is not an affiliated link]

This is a different product than the free Dynamics CRM administration toolset, XrmToolbox.

I find this product invaluable. Not only does it allow me to edit my JavaScript (and other code like plugins) inside of Visual Studio, but it will also publish back to Dynamics CRM with merely a button-click. 

And as I mentioned in #1, once we have the code inside of Visual Studio, we can add it to source control and have it safe and secure in the Microsoft cloud somewhere.


Well, that’s my two cents for the day. Have a great weekend.

Thanks, Mitch

Dynamics CRM SDK Version 8.1.0 Release Notes

The Dynamics CRM SDK was updated on 6 May and here is a list of the changes.

Apply SLAs to entities

New topic containing information about the SLA support for various entities in CRM.

Azure integration with Microsoft Dynamics CRM

Work with CRM event data in your Azure Event Hub solution

Write a listener application for a Microsoft Azure solution

Walkthrough: Configure Microsoft Azure (SAS) for integration with Dynamics CRM

Walkthrough: Update a service endpoint from ACS to SAS authorization

Walkthrough: Update a service endpoint imported from a solution

New or updated Azure related topics containing information about new features including SAS authorization, support for event hubs, and multiple messaging data formats for cross-platform interoperability.
The restriction to use the Azure SDK version 1.7 or 1.8 has been changed to version 1.7 or later.

Create packages for the CRM Package Deployer

Updated the topic to include information about the new capabilities that enable developers to control how the packages will be deployed while creating packages.

Default SiteMap XML

Updated the topic about the inclusion of the interactive service hub in the default CRM sitemap.

Knowledge base search control (client-side reference)

Updated the topic to include information about the new client APIs in this release.

Microsoft Dynamics CRM Web API Limitations

Added the following additional limitations:

•    Can't query date values
•    Web API not enabled for Microsoft Dynamics CRM for Outlook with Offline Access while user is offline

Query Data using the Web API

Added the following sections about CRM Web API enhancements in this release:
•    Filter records based on single-valued navigation property
•    Retrieve related entities by expanding navigation properties

ServiceEndpoint entity messages and methods

The ServiceEndpoint entity has new attributes for SAS configuration. The NamespaceAddress and NamespaceFormat attributes have been added to support full namespace addressing in addition to the existing option of specifying just the namespace name.

Use the Category entity to categorize CRM records

Category entity messages and methods

Topics added that contain information about how you can use the new Category entity.

Use the Feedback entity to manage feedback and ratings for CRM records

Feedback entity messages and methods

New topics containing information about how you can use the new Feedback entity.

Write and debug scripts for CRM for phones and tablets

Renamed the topic from Write and debug scripts for CRM for tablets, and updated the contents to include information about the client API support for CRM for phones and tablets.

Write and debug scripts for the interactive service hub

New topic containing information about the client APIs supported in the interactive service hub.

Write code for Microsoft Dynamics CRM forms

Added entities to list of Updated entities that now support the improved form rendering experience in CRM.

Bad Design: A tale of De-Architecture and De-Engineering

Every one of us has been guilty, or will be guilty, of creating a bad solution to a problem at some point in our career. If you have not done so yet, just be prepared, your day will come. Smile

Most of the time, people do not start off trying to create a bad solution, it just ends up like that. The cause can be just about anything, but here are a few:

  • Bad information (from research or the customer)
  • Change in design of Dynamics CRM (i.e., they changed something and didn’t tell you)
  • Assumptions
  • Over-thinking a problem
  • Under-thinking a problem
  • Unfamiliarity with the product, its features, and functionality points


Back in 2011 I inherited a customer from another consultant who was too busy to handle the upgrade from CRM 4.0 to 2011. The system had been fairly customized and had a variety of plugins and a fair amount of JavaScript.

One of the things that had been done was to modify the calculations of the Quote/Order/Invoice system in order to incorporate a customer-requested design change.

When I saw the code, and there was a lot of it (plugins and JavaScript), I question the consultant on why it had been done this way. His reply was, “they had very specific requirements about how everything was calculated.”  Looking at the code, I could honestly not see what would have caused anyone to rewrite the calculation engine, but that is what had been done.

The main part of the customization was that custom total fields were added and the calculated values were stored in those fields while also updating the original total fields with the custom calculations.

The one thing that was different and extremely important was a custom field that allowed the user to enter a specific price per unit that would take the place of any system-calculated price.

So I upgraded everything, cleaned up the code a bit, and everything continued to work as designed/requested.

Then we upgraded to CRM 2015, and things started to NOT work as design.  Specifically with the Opportunity Product.  You would change a value and see before your eyes, the numbers change.

After spending about 3 hours one night tracing the actions of the system, I found this flow:

  1. User changes the quantity on the form
  2. Our custom JavaScript fires
  3. Internal CRM JavaScript fires which performed a calculation and saved the record
  4. Our custom Plugins fire
  5. [Possibly] Internal CRM plugins fire

The net result of this was that Dynamics CRM was overwriting our newly calculated values with their own, which was driving the users crazy.

Dynamics CRM Internals Notes

If you did not know, the Quote, Order, and Invoice entities are exactly the same, just in different buckets. Also, the Opportunity Product, Quote Product, Order Product, and Invoice Product entities also share the same structure.

These entities are really hard to customize because there is a fair bit of magic that happens behind the scenes through either JavaScript or Plugins, or both.

Also, even though these entities are similar in layout and design, it would appear that do not all function exactly  the same.

Also, everything is version-specific.  With CRM 2015, only the Opportunity Product uses the new form design. Quote/Order/Invoice Products still use the Information form.

Also remember that starting with Dynamics CRM 2013, the QOI and Opportunity forms were all redesigned to use the new layout which includes an editable grid for the Product line items. Since you can create records from the grid, and even change some fields, keep in mind that any JavaScript on the Product detail form will never be executed.

Any work that must be done on the create of one of these records must be accomplished using a plugin.

The Problem

The main problem was the internal Dynamics CRM code was overwriting the results of our custom code – somewhere – and after reviewing the facts, I realized there was just no way I could circumvent the actions of the product.

Correcting the Problem

The solution to this problem was actually rather simple and I still wonder why this wasn’t tried before.

It turns out that there is a Manual Discount field which is actually used by the automatic calculation engine.  After spending about 30 minutes with the customer, we were able to successfully test the use of the Manual Discount field as the basis for our custom per unit price.

I used that field to reduce the price per unit so that the calculation appeared to be using the manually entered price per unit, even though it was not. The code looks like this:

Code Snippet
  1. function newDiscountCalculation() {
  2.     if (Xrm.Page.getAttribute("new_netpriceperunit").getValue() == null) {
  3.         Xrm.Page.getAttribute("manualdiscountamount").setValue(0.00);
  4.         return;
  5.     }
  6.     var priceDifference = Xrm.Page.getAttribute("priceperunit").getValue() –
  7.                           Xrm.Page.getAttribute("new_netpriceperunit").getValue();
  8.     if (priceDifference === 0) {
  9.         return;
  10.     }
  11.     var manualDiscount = (priceDifference –
  12.                           Xrm.Page.getAttribute("volumediscountamount").getValue()) *
  13.                           Xrm.Page.getAttribute("quantity").getValue();
  14.     Xrm.Page.getAttribute("manualdiscountamount").setValue(manualDiscount);
  15. }


So that took care of the data issue, the remainder of the problem was corrected by removing ALL of the custom JavaScript and Plugins that also performed the calculations.

The only issue that remained was we had years worth of data in the wrong fields and many of the additional functionality points: Templates, reports, etc., were using these custom total fields.

Final Results

So here are the results of this process:


As far as the users go, there was not change to the functionality they have been using for the past 7 years or so.


I decommissioned and removed five plugins because their function was either unnecessary or redundant. The plugins that currently exist perform addition functions but the only pricing-related things they do are to put the values from the standard total fields into the custom total fields because those are the fields that are being used throughout the entire system.


About 95% of the JavaScript related to these entities was removed. Most of the work is actually done in the QOI Product entities and since the fields are named the same, I was able to have a single JavaScript library shared among all of these entities.

Lessons Learned

You’ve probably heard me say this many times but it is never a good idea to recreate Dynamics CRM built-in functionality.  Sooner or later you will pay the price for that decision and it is never pretty.

So, don’t do it.

Setting a Dynamics CRM field’s value to Title Case using JavaScript

In a thread on one of the community forms, Debra asked how to properly add some JavaScript she had found on another forum post to make the first letter in each word uppercase (while the remainder is lower-case). This is called title-case, by the way.

Taking the code that Debra mentioned, I modified it a bit, and ended up with this:

function upperCaseField(executionContext) {
    var field = executionContext.getEventSource()


function toTitleCase(str) {
    return str.replace(/\w\S*/g,
                       function(txt) {
                            return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();

It is configured on an individual field like this:


It is most imperative that you check the box for Pass execution context as first parameter.  If you do not, then the function will fail.

If you wish to add this function to multiple fields, you can do so using this technique, as mentioned in that thread by @aileengusni:

function form_OnLoad() {


Repurposing Dynamics CRM Fields. Just Say No!

I was preforming a pre-upgrade cleanup for a customer when I ran into this:


As you can see, they took a relatively unused field, Address 1: County, and repurposed it and called it Current Software.

This is a very, very, bad thing.

For one, it is totally unnecessary.  Maybe back in the 1980’s when we measured things in kilobytes and megabytes; where gigabytes was just something on a mathmagician’s chart.

But that is not today, when people regularly, and with a straight face, speak of and use petabytes and beyond.

Don’t let me catch you doing this. It is just plain bad design and can lead to fascinatingly odd problems to fix.

Now Available: Fun with fields, a Dynamics CRM Customization Training Guide

Happy Friday Everyone,

I have just released a new training guide for those of you interested in growing your Microsoft Dynamics CRM knowledge.

The purpose is to walk you through the creation of every type of data entry field, format, and behavior available within the Dynamics CRM system.

It was written against Dynamics CRM 2016, so some of the newer features will not be available within earlier versions, but much of the basics will.

Check it out here.

Have a great weekend.


Readonly Fields and The Dynamics CRM Workflow Editor

I ran across an issue this week creating a workflow for an entity that had fields set to read-only.

If you’ve never run across this before, setting the Read Only property on a field will not only restrict the modification of field data to the user, but also when working with the CRM workflow editor.

There are several ways around this type of problem:

Option 1: JavaScript

The first option you have is to use JavaScript to set the fields in question to disabled, using the Form Type to determine when that piece of code should work.

While this works, there is now an extra piece of code that must be maintained by someone.

Option 2: Manually change the fields

The second option is for you to remove the read only property from the fields, publish the entity, create your workflow, then reverse the process and make the fields again read only.

While this works, it is a serious pain in the neck and not very maintainable, should you need to make frequent changes.

Option 3: Business rule

I have not tried this option, but I think it is possible, but I don’t have direct knowledge of the interaction between the business rules and the workflow editor.

Another topic for a future blog.

Option 4: Administration Form

This is, by far, the most elegant solution I think, and the one I chose to implement:

Tip #265: Administrator updates of read-only fields

Dynamics CRM JavaScript: Ensure the current record is Saved before opening a new record

In yesterday’s post, Tracing the Dynamics CRM Form Data save Operation, I discussed identifying data that would be sent to the database when you saved a Dynamics CRM record.

Part of the issue I was facing was related to the form not completing the save operation before I opened a new form record. Since Dynamics CRM 2013 and 2015 user interface rarely opens a new window, the user was getting a warning that there was unsaved data when the page was being switched between the Account and, in this case, the Opportunity record.

So to prevent this from happening, I had to wait for the save to complete then open the new Opportunity record.

Here is the code where I do that:


var parameters = { customer_id: customerId, customer_name: customerName, customer_type: customerType, name: Xrm.Page.getAttribute("name").getValue() }; var windowOptions = { openInNewWindow: true }; setTimeout(function () { openNewForm(parameters); }, 2000); } function openNewForm(parameters) { var windowOptions = { openInNewWindow: true }; Xrm.Utility.openEntityForm("opportunity", null, parameters, windowOptions); }

The Details

We are using the JavaScript method setTimeout to wait for 2,000 milliseconds (2 seconds for those of us who are not computers).

At the end of the wait period, we will call a function called openNewForm which will use the Dynamics CRM method Xrm.Utility.openEntityForm, which opens a new Opportunity form.

You may need to adjust the wait period up or down, depending on your environment. The idea is to wait long enough for the save to complete, but not long enough to irritate the user.

Dynamics CRM JavaScript: Working with Tabs and Sections-The right way

Back in March I wrote the following article: Dynamics CRM Developer Tip O’ the Day: Working with Tabs.

Today I was working on some pre-existing customer JavaScript and ran across this:

Xrm.Page.ui.tabs.get(0).sections.get(6).setVisible(false); // Hide section

Don’t ever do that! Bad developer! Bad!

So again, never, ever use the numerical value to reference a Tab or a Section, unless you have no choice. 

We don’t want to use numbers because if you move or add Tabs or Sections, your code will no longer work.

Do this instead:

Xrm.Page.ui.tabs.get("General").sections.get("Details").setVisible(false); // Hide section

As long as your Tabs and Sections are named properly, you should not have an issue.

Manually Repairing a Sitemap. Part 1

As I mentioned a couple of week ago, my upgrade from CRM 2013 to CRM 2015 did not go well. One of the issues is my SiteMap was totally broken and I had to replace it with the “default.”

The only problem was I wiped out the custom entries for my marketing package, Click Dimensions.

No problem, I thought, I’ll just add the solution back.  Except that did not work.  I ran into ghost SiteMap entries from a previously remove solution. This required a call to Microsoft Support to get them corrected.

Once corrected, I was successfully able to import the solution.  Except there were no custom SiteMap entries.

Only only solution in this case is to manually add them, which involves this process:

The Process

1. Create a new solution.

2. Add the SiteMap to the solution.

3. Export the solution as unmanaged.

4. Unzip the solution files.

5. Take the solution file from the package you are attempting to import and unzip it as well.

6. Open the customization.xml file from step 4 in an editor like Visual Studio or Notepad++.

7. Open the customization.xml file from step 5 in an editor like Visual Studio or Notepad++.

8. Copy the information from the step 7 SiteMap and paste it into the proper location within the step 6 SiteMap.

9. You will need to remove some XML attributes that are specific to the Solution Import process. Here is an example:

<Group Id="Extensions" ResourceId="Group_Extensions" ordinalvalue="5" solutionaction="Added" />

You need to remove the any reference to ordianvalue and solutionaction.

10. Save the step 6 customization.xml file.

11. Re-Zip the files from step 4.

12. Import the solution back into CRM.

13. Refresh your browser and see if the SiteMap changes worked.

Things to Know

I did not get into great detail about the SiteMap itself because you really have to understand how it is organized and all of the components that are involved. If you do not understand these things, you can damage the SiteMap and render your CRM system inaccessible.

Before you start anything like this, please know and understand what you are doing.  See the references below.

If all else fails, open a case with Microsoft.


Edit the site map

SiteMap XML reference