Restore Add Activity buttons in CRM 2013

By default the CRM2013 form Command Bar doesn't show the old 'Add' tab buttons for activities. The intension is that users will want to use the new Activities Tab control on the forms as show below:

In an upgrade from CRM 2011 you may want to preserve the add activity buttons on a form. This post describes how you can easily bring back those add activity buttons using the Ribbon Workbench. 1) Create a solution containing the entities that you wish to restore buttons for. I am using the Account entity for this post. 2) Open the solution containing the Account entity in the Ribbon Workbench for CRM 2013 and select the 'account' entity if not already selected. You will see by default the Command Bar is selected.

3) Select the Ribbon tab to show all the buttons that are defined. 4) Select the 'Form' ribbon using the drop down in the top right corner of the design surface and then select the 'Add' tab. You should now see the CRM 2013 activity buttons.

5) Right click on the phone call button and select 'Customise Command'

6) In the 'Solution Elements' panel expand the 'Commands' node and select 'Edit Display Rules'

7) Select the 'Mscrm.HideOnCommandBar' rule and click 'Remove'. If you do not see this rule, then it is likely that you have forgotten to select the 'Form' ribbon in step 4 above.

8) Click OK and then repeat for each of the add buttons that you want to restore. 9) Since we are not customising the enable/display rules – only the command, expand the Enable Rules and Display Rules node, and for each rule that is prefixed with Mscrm, select and set the 'IsCore' property to 'False'.

Display Rules

Mscrm.HideOnCommandBar Mscrm.AddActivityToPrimary Mscrm.WriteActivityPermission

Enable Rules

Mscrm.AppendToPrimary Mscrm.FormStateExistingOrReadOnly

10) Click 'Publish' and your form should now show the activity buttons who's command's you customised.


Using the CRM 2013 Developer Toolkit to target CRM 2011

If you find yourself constantly juggling multiple development environments, you'll no doubt come up against the issue of the Developer Toolkit only supporting a single installation – either for CRM 2011 or CRM 2013. To overcome this, I have been using the CRM 2013 version again CRM 2011 with no issues. The only thing to remember is that if you create a new project that needs to target CRM 2011, you must remove the version 6 assemblies from your plugin and workflow projects and re-add the version 5 ones. You can do this using nuget with a specific version: Install-Package Microsoft.CrmSdk.CoreAssemblies -Version 5.0.17 See my post for more information. @ScottDurow

CRM 2013 Script Loading Deep Dive

Ever since the script Web Resource loading behaviour changed in UR12 from series to parallel I've been interested in how to best standardise management the loading of script Web Resources. The fact that scripts are loaded from a variety of places makes the subject even more interesting. This post attempts to answer all of my questions about how scripts are loaded. In order to fully understand how CRM 2013 loads scripts I examined the following script load points: 1. Form Libraries Each form can specify multiple libraries, and a set of Events Handlers that are called when the form is loaded.

  1. Ribbon Xml Command Actions Command Bar JavaScript functions that are called when a Command Bar button is clicked. Multiple JavaScriptFunctions can be included in a Command Action and is often used to specify dependency scripts. The following example shows common.js being a dependency to library.js. The 'isNaN' function is simply a dummy function call because common.js only needs to be loaded. <Actions> <JavaScriptFunction FunctionName="isNaN" Library="$webresource:newcommon.js" />
    <JavaScriptFunction FunctionName="fooBar" Library="$webresource:new
    library.js" /> </Actions>

  2. Ribbon Xml Enable Rule Enable Rule JavaScript functions are evaluated to determine if a Command Bar is enabled (visible). Again, multiple functions can be specified for an enable Rule and is often used to specify dependency scripts in the same way as shown above for Command Actions. <EnableRule Id="new.newvaluerulestest.BoolYes.EnableRule"> <CustomRule FunctionName="isNaN" Library="$webresource:new common.js" /> <CustomRule FunctionName="fooBar" Library="$webresource:new_ library.js" /> </EnableRule>

Approach I created 6 scripts that each used console.log to write messages as they were loaded and when the functions were being executed. I also used Fiddler to introduce latency into the script downloads so that I could see the order that they were being requested. The terminology I use is in the results are as follows:

Script Download - The process of downloading the script web resource from the server. Script Load – The actual evaluation of the script once it has been downloaded from the server. The script load defines any functions and object prototypes. If you have any code that is not contained within a function, then it will be executed at this time. Script load order becomes important when the Script Load includes references to functions that exist in other libraries such as name spacing functions or jQuery constructs. It is advisable to keep these kind of dependencies to a minimum due to requirement to have scripts loaded in a particular order. Script Event Handler – Function registrations that are called on form events such as OnLoad or OnChange that call a function in a loaded script web resource. The Event Handers are different to the Script Load in that the Event Handler is called after the Script has been loaded. Executed – If there is a function that is referenced by an Enable Rule or Command, the function is executed after the script is loaded.

Here are the things you need to know! The following section summaries the results I discovered from my deep-dive: Form Scripts 1) Form Script will download in parallel unless they are already loaded by an EnableRule. 2) Form Scripts are not guaranteed to load in the order that they are specified in the form properties. They will be requested asynchronously in parallel and then loaded in the order that they received from the server. This is similar to the CRM2011 UR12-UR14 behaviour meaning that you can't guarantee that a dependency script is loaded before a dependant script without using some custom code to handle dependencies. 3) Form Script OnLoad Event Handlers will execute only after ALL script specified in the Form properties are loaded.

4) Form Scripts that are loaded only by the Form (and not Enable Rules) will appear as a 'normal' script element with WebResource URL in the IE F12 debugger. Enable Rules 1) EnableRule CustomRule Scripts are downloaded, loaded & executed in series and in the order they are specified in the EnableRule. The next script is loaded after the previous one has been loaded and executed.2) EnableRule functions are executed immediately after their script is loaded and before the OnLoad form even handler. The function is re-evaluated if the ribbon is refreshed and when the button is clicked (before the command action is executed).

3) Form Scripts will start downloading after all Enable Rule Scripts have been loaded and executed. The Command bar is then available before the form on-load event has been run.

4) An interesting by-product of the fact that Enable Rules load in series before the form scripts is that if you specify the same scripts in an Enable Rule that are referenced by the Form, your scripts will always load in the correct order! I had some situations like this on an upgrade from CRM2011 and I couldn't work out why on some forms the scripts were loaded in series and some in parallel. 5) Scripts loaded by EnableRules will appear as dynamic 'script block' and not a named WebResource URL in the IE F12 debugger. Commands 1) Command Action JavaScript Function scripts are loaded and executed in series and in the order that they are specified in the Command. 2) Command Action scripts are loaded when the button is clicked and not when the page is loaded (unless they are used by the form or enable rules in which they are already loaded). 3) Scripts loaded by Command Actions will appear as dynamic 'script block' and not a named URL in the IE F12 debugger.

4) I found an interesting boundary condition that if the same scripts were used in the form load and in command actions; you could click the button before all the scripts were loaded so that only part of the command would run. This would have the potential to cause script errors if a user clicked on a command button before the on-load event had fired. General 1) Scripts are loaded only once per page even if they are referenced in multiple places (Commands, EnableRule and Form Libraries). Script Loading Process Flow So that you can fully understand the script loading process, I've attempted to show a good approximation in flow chart form.

Key points of note on the flow:

Enable Rule Scripts are loaded in series Form Scripts are loaded in Parallel. Command Action Scripts are loaded in series

Command Actions can be executed before the Form Scripts are loaded.  

Working around the parallel loading of Form Scripts When parallel loading of scripts first became an issue in CRM2011 with UR12 I used a timeout style approach to waiting for dependant scripts to load. You can read more about this on my blog post on the subject. Now rather than use a timeout wait, I feel that a more deterministic approach would be more suited. By wrapping the script web resources in the following, my tests showed that were always loaded in the correct order. The scriptLoader uses a dependency registration mechanism that allows registration of scripts to be loaded only when all of the dependant scripts are also loaded. var scriptLoader = scriptLoader || { delayedLoads: [], load: function (name, requires, script) { window.loadedScripts = window.loadedScripts || {}; // Check for loaded scripts, if not all loaded then register delayed Load if (requires == null || requires.length == 0 || scriptLoader.areLoaded(requires)) { scriptLoader.runScript(name, script); } else { // Register an onload check scriptLoader.delayedLoads.push({ name: name, requires: requires, script: script }); } }, runScript: function (name, script) {; window.loadedScripts[name] = true; scriptLoader.onScriptLoaded(name); }, onScriptLoaded: function (name) { // Check for any registered delayed Loads scriptLoader.delayedLoads.forEach(function (script) { if (script.loaded == null && scriptLoader.areLoaded(script.requires)) { script.loaded = true; scriptLoader.runScript(, script.script); } }); }, areLoaded: function (requires) { var allLoaded = true; for (var i = 0; i < requires.length; i++) { allLoaded = allLoaded && (window.loadedScripts[requires[i]] != null); if (!allLoaded) break; } return allLoaded; } };

scriptLoader.load("Script Name", [("Dependency Script 1","Dependancy Script 2"}, function () {

// TODO: Your script goes here!


You must encapsulate every form script that is a dependant or a dependency. The load function has the following parameters:

Name – Specify a unique name of each of your scripts Requires – Specify an array of script names that must be loaded before the current one is loaded.

Of course, the script can be minified to reduce its impact on your individual Web Resources. Conclusions Armed with the information I've discovered in this deep-dive, I feel I'm equipped to make the right decision when designing solutions that include multiple script Web Resources. @ScottDurow    

Manage your SDK assemblies the easy way

NuGet has become the de-facto way of managing assembly references from within Visual Studio. Using the Package Manager you can easily download, install, update and uninstall referenced libraries automatically from the ever growing NuGet library repository. In the past there was an unofficial package, but with the release of CRM2013, the SDK team have made the official assemblies available on NuGet. You can install the references to the CRM2013 SDK assemblies by Right Clicking on your Project from within Visual Studio and selecting Manage NuGet Packages…

If you search for Microsoft.CrmSdk in the Online tab, you will see a list of the official SDK assemblies.

Here are 5 really great things about using NuGet:

All referenced assemblies are stored in a single solution folder named packages so that each project will reference the same assembly version inside your solution. You can update to the latest version using the 'Updates' tab inside the NuGet Package manager (or a specific version using the command line package manager). Any dependency assembly packages (e.g. IdentityModel) will automatically be downloaded and referenced in your solution You don't need to commit your dependency packages to Source Control. If you commit only your code to source control and then try and build the project on a new environment, you can easily re-download the assemblies from within the Package Manager using the 'Restore' button.If you want to automatically restore these files on build – you can Right Click on your solution and selecting 'Enable NuGet Package Restore'. See the article on the NuGet site for more information. You can use either the package manager to discover and install your packages, or use the NuGet Console to quickly install/uninstall if you know what you're looking for (Tools-> Library Package Manager - >Package Manager Console)

The package inter-dependencies with their names as referenced in NuGet are as follows:

You can see all of them listed at Using the Package Manager Console you could install the latest Core Assemblies for CRM2013 using: Install-Package Microsoft.CrmSdk.CoreAssemblies Or you could install the CRM 2011 version using: Install-Package Microsoft.CrmSdk.CoreAssemblies -Version 5.0.17 If you wanted to install them you can use: Uninstall-Package Microsoft.CrmSdk.CoreAssemblies Start using NuGet if you are not already and you'll never look back! @ScottDurow

Upgraded to Orion? Upgrade to Ribbon Workbench for CRM2013

If your Dynamics CRM Online instance has been upgraded to Orion (CRM2013) you will need to upgrade to the latest version of the Ribbon Workbench for CRM2013. Since the Ribbon Xml Schema has changed slightly with CRM2013, the old version will no longer work. Upgrade Steps:

Open Settings->Solutions. Locate the Ribbon Workbench solution and click 'Delete' Download and Import the Ribbon Workbench for CRM2013. Refresh your browser and navigate to Settings->Solutions where you will find the new Command Bar button:

Further reading:

Ribbon 'XML' Workbench for Dynamics CRM 2013 with a silent 'XML'! 4 things you need to know about the Command Bar Restore a Button that has been removed from the CRM 2013 Command Bar


How to fix CRM2013 Application Bar hidden by Silverlight Web Resource

If you have any Silverlight Web Resources in your site map that are hosted by an HTML Web Resource, you may find that when you upgrade to CRM2013 and use the pull down Application Bar the Silverlight page is rendered on top of the navigation buttons so that they are obscured and hidden from the user. It might look something like the following:-

To fix this you need to adjust the Windowless property in the Silverlight object: <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> <param name="Windowless" value="true" /> Other than this I've not had any issues with Silverlight in CRM2013 but there is now a nice phrase in the SDK that states: "Microsoft Silverlight web resources remain supported in Microsoft Dynamics CRM 2013 and Microsoft Dynamics CRM Online for backwards compatibility. For components that will be able to be presented on all clients, we recommend using HTML web resources with HTML5 instead of Silverlight." If you need to convert your Silverlight Web Resources to HTML 5 and JavaScript, you could check out @ScottDurow

Microsoft.Xrm.Client (Part 3b): Configuration via app/web.config

In this series we have been looking at the Developer Extensions provided by the Microsoft.Xrm.Client assembly: Part 1 - CrmOrganizationServiceContext and when should I use it? Part 2 - Simplified Connection Management & Thread Safety Part 3a – CachedOrganizationService So far in this series we have learnt how to use the Microsoft.Xrm.Client developer extensions to simplify connecting to Dynamics CRM, handling thread safety and client side caching. This post shows how the configuration of the Dynamics CRM connection and associated OrganizationService context can be configured using an app.config or web.config file. This is esspecially useful with ASP.NET Portals and Client Applications that don't need the facility to dynamically connect to different Dynamics CRM Servers. If you only want to configure connection string, then you would add a app.config or web.config with the following entry: <connectionStrings> <add name="Xrm" connectionString="Url=http://<server>/<org>"/> </connectionStrings> The Connection string can take on the following forms:

On Prem (Windows Auth)


On Prem (Windows Auth with specific credentials)

Url=http://<server>/<org>; Domain=<domain>; Username=<username>; Password=<password>;

On Prem (Claims/IFD)

Url=https://<server>; Username=<username>; Password=<password>;

On Line (Windows Live)

Url=https://<org>; Username=<email>; Password=<password>; DeviceID=<DeviceId>; DevicePassword=<DevicePassword>;

On Line (O365)

Url=https://<org>; Username=<email>; Password=<password>;"

You can find a full list of connection string parameters in the SDK You can then easily instantiate an OrganizationService using: var connection = new CrmConnection("Xrm"); var service = new OrganizationService(connection); If you want to simplify creation of the ServiceContext, and make it much easier to handle thread safety – you can use a configuration file that looks like: <configuration> <configSections> <section name="microsoft.xrm.client" type="Microsoft.Xrm.Client.Configuration.CrmSection, Microsoft.Xrm.Client"/> </configSections> <microsoft.xrm.client> <contexts> <add name="Xrm" type="Xrm.XrmServiceContext, Xrm" serviceName="Xrm"/> </contexts> <services> <add name="Xrm" type="Microsoft.Xrm.Client.Services.OrganizationService, Microsoft.Xrm.Client" instanceMode="[Static | PerName | PerRequest | PerInstance]"/> </services> </microsoft.xrm.client> </configuration> You can then instantiate the default context simply by using: var context = CrmConfigurationManager.CreateContext("Xrm") as XrmServiceContext; The most interesting part of this is the instanceMode. It can be Static, PerName, PerRequest, PerInstance. By setting it to PerRequest, you will get a OrganizationService per ASP.NET request in a portal scenario – making your code more efficient and thread safe (provided you are not using asynchronous threads in ASP.NET). The examples above I find are the most common configurations, although you can also specify multiple contexts with optional caching if required for specific contexts – the SDK has a full set of configuration file examples. Using the configuration file technique can simplify your code and ensure your code is thread safe. On the topic of thread safety, it was recently brought to my attension that there appears to a bug with the ServiceConfigurationFactory such that if you are instantiating your OrganizationService passing the ServiceManager to the constructor in conjunction with EnableProxyTypes, you can occationally get a threading issue with the error "Collection was modified; enumeration operation may not execute". The work around to this is to ensure that the call to EnableProxyTypes is wrapped in the following: if (proxy.ServiceConfiguration.CurrentServiceEndpoint.EndpointBehaviors.Count == 0) { proxy.EnableProxyTypes(); } More information can be found in my forum post. Next up in this series are the Utility and extension functions in the Microsoft.Xrm.Client developer extensions. @ScottDurow  

Asynchronous loading of JavaScript in CRM 2013

When CRM2011 UR 12 (POLARIS) introduced asynchronous loading of web resources, there were some unfortunate side effects caused by the load order in which the scripts were executed not being the same as defined by form customisations. If you had scripts that required a previous scripts to be loaded first before it could be executed, you would experience random script errors due to the unpredictable load order. You can read more about the issue in the MSDN forums thread and the blog post I wrote explaining the behaviour and workaround. Since then, the behaviour has been reverted back to the pre-UR12 loading technique as of Dynamics CRM2011 UR15 but this post describes what you can expect from Dynamics CRM 2013's script loading mechanism. Why Asynchronous? One of the reasons for moving to an Asynchronous loading model for JavaScripts was to make the form feel more responsive. Rather than having to load all scripts first before code can start and the form can be rendered, the scripts are loaded in parallel (as far as the browser will let them) resulting in a faster load time compared to a sequential load. Code that has all of its dependencies loaded can also start running before all of the unrequired scripts have completed being downloaded. Libraries such as RequireJs handle the complexities that can result from interdependent scripts all loading in parallel and your code needing to know when its dependencies are loaded before executing. CRM2013 scripts do not load in order With Dynamics CRM 2013, scripts are now loaded asynchronously and although the onload event will be executed after all scripts are loaded, the loading of the individual scripts will happen in the order that they are received from the server and not the order that they are specified in the form properties. Of course how you load JavaScript in Html Web Resources is still up to you! Debugging Scripts One by-product of this dynamic loading of scripts is that you won't see your web resources in the list of scripts using the F12 debugger since the browser has no <SCRIPT> tag to get the URL from. The script will still be available for debugging; however it will appear as an anonymous script block rather than in the list of script sources against its web resource URL. The technique I describe in the 'New Project' SparkleXrm tutorial of using to create a re-direct to a script on the disk will still work because the browser request the web resource by its URL, allowing fiddler to intercept and redirect. Caching behaviour is unchanged with the web resources being cached by the client until customisations are published and the cache version is changed. You can read more about this mechanism in my web resource caching blog post on the subject. Fast and Responsive The good news is that as a result of the changes – forms are noticeable faster to load. @ScottDurow

4 things you need to know about the Command Bar

This post provides the important information you need to know in order to transition to customising the Command Bar in Dynamics CRM 2013. 1. The Command Bar is a Ribbon in disguise! The Ribbon Bar in Dynamics CRM 2013 to a certain degree has been replaced by the Command Bar but it still exists on non 'refreshed' entity Forms such as Connection Form and Price List Form, and is still present on all home list view grids in Microsoft Outlook. The Command Bar is actually the same Ribbon structure but rendered differently in the User Interface. Although the Command Bar has no visual concept of Tabs, Groups or Layouts and there is no dynamic resizing and scaling, it still requires the Ribbon Diff Xml with these constructs to function. Using the Ribbon Workbench for CRM2013 will allow you to still edit these structures, but view in both the Command Bar and Ribbon display format. 2. Disabled Buttons are hidden The Command Bar will only show 5 controls at any one time before they are added to the 'overflow' section. This deliberate constraint means that you will need to think carefully about what the user really needs on their command bar. Initially this may sound like a tricky problem but the Command Bar will not display a disabled button – it will always hide it – which means that the 5 buttons being shown will dynamically change depending on what buttons are available to the user. This is a significant improvement over the Ribbon that would always look cluttered even if there were very few buttons enabled for use. To work with the 5 control constraint you can use fly out and split buttons to group commands together and not be moved to the overflow. The Overflow menu can also have fly out controls that open to the right rather than pulled down.

  1. No contextual Sub Grid Controls CRM2011 form Sub Grids used to dynamically swap in the Sub Grid Ribbon at the top of a form when a sub grid was selected. This allowed access to the sub grid entity commands directly from the parent entity form but often left a user confused. This functionality has been removed in CRM 2013 and the primary entity Command Bar now always is shown at the top of the form. A new 'mini' Command Bar is shown above each form Sub Grid showing only the 'Add' and 'Open Associated Sub Grid' buttons with the Delete button shown next to each record. If you want to access all of the sub grid buttons you must use the 'Open Associated Sub Grid' button that opens the entire page into the Sub Grid list view. To return to the form you must click on the name of the record in the Nav Bar. You cannot customise this mini Sub Grid at this time other than overriding the 'Add' and 'Delete' command - you cannot add buttons or change the icons of buttons on the mini Sub Grid, but full customisation is supported on the full Sub Grid Command Bar.

  2. Controlling Visibility of Controls on the Command Bar The visibility of a control on the command bar is defined using a new Display Rule named 'CommandClientTypeRule'. Controls will only show on the Command Bar if their associated Command has no CommandClientTypeRule Display Rules or it has a CommandClientTypeRule is added with Type=Refresh. The Types property can have the following values:


The control is visible in the Tablet client


The control is visible in the Command Bar


The control is visible on ribbons of non-refresh entities or in list views presented in Microsoft Outlook.

There is a built in Display Rule that is used to hide system buttons from the Command Bar named 'Mscrm.HideOnCommandBar' that has a 'CommandClientTypeRule' with Type=Legacy. Commands with this Display Rule will not be visible on the Command Bar. You can remove this display rule from command to bring back buttons that were hidden by default. I have created instruction on how to do this. Clean and Responsive These 4 points will make planning & designing your CRM2013 solution easier and I'm sure you'll soon be loving the clean and responsive user experience that the new Command Bar gives. @ScottDurow

How to change process and stage programmatically

Scenario UPDATE: With CRM2015 - the new client side process API should be used to set the current step. The following approach should be only used for setting the process to the first step. If you have more than one Dynamics CRM 2013 Business Process Flow for a given entity users can easily change the current process by using the 'Switch Process' Command Bar button:

Once changed, you can identify which process is running by hovering over the 'I' on the bottom right of the process flow:

If your users would like to change the Business Process Flow stage dynamically based on a given set of attribute values then it is not immediately obvious how this can be achieved. This post provides one solution using a custom workflow activity in combination with the new Synchronous Workflow feature of Dynamics CRM 2013. Solution The currently selected process stage on a given entity record is stored in CRM using the following attributes:

processid – GUID of the selected Business Process (workflow) stageid – GUID of the selected Process Stage (processstage)

Initially I thought that these attributes might be able to be updated using a workflow directly, but it turns out you can only update them via code. You will need to know how to write Custom Workflow Activities and add JavaScript Web Resources to follow these steps: 1. Using the Visual Studio Developer Tookit found in the SDK, create a new Custom Workflow Activity that accepts the following input arguments: [RequiredArgument] [Input("Process Name")] public InArgument Process { get; set; }

[RequiredArgument] [Input("Process Stage Name")] public InArgument ProcessStage { get; set; } These parameters need to be strings since you cannot pass in EntityReferences to the Workflow and ProcessStage entities. 2. Add to the Execute code the following: using (var ctx = new OrganizationServiceContext(service)) {
// Get the processid using the name provided var process = (from p in ctx.CreateQuery() where p.Name == Process.Get(executionContext) && p.StateCode == WorkflowState.Activated select new Workflow { WorkflowId = p.WorkflowId

if (process==null)
    throw new InvalidPluginExecutionException(String.Format("Process '{0}' not found",Process.Get(executionContext)));

// Get the stage id using the name provided
var stage = (from s in ctx.CreateQuery()
             s.StageName == ProcessStage.Get(executionContext)
             s.ProcessId.Id == process.WorkflowId
             select new ProcessStage
                 ProcessStageId = s.ProcessStageId

if (stage == null)
    throw new InvalidPluginExecutionException(String.Format("Stage '{0}' not found", Process.Get(executionContext)));

// Change the stage
Entity updatedStage = new Entity(context.PrimaryEntityName);
updatedStage.Id = context.PrimaryEntityId;
updatedStage["stageid"] = stage.ProcessStageId;
updatedStage["processid"] = process.WorkflowId;


  1. Deploy your custom workflow activity.
  2. Create a New Workflow that is defined with the following parameters:

Activate As: Process Run this workflow in the background : NO Scope: Organization (if you want it to run for all users) Start when: Before – Record fields change. Select the attributes that the process stage is dependant on so that it does not run on every change.

  1. Add a set of conditions to determine if the stage should be changed and call your custom workflow activity providing the Process Name and Process Stage to change to.

  2. Since the Process and Stage will not automatically change on the form, you need to add some JavaScript to refresh the form by saving it when the dependant fields are changed. You can do this by adding an onChange event to the dependant fields that calls: UPDATE: Rob Boyers pointed out that this doesn't reliably refresh the process, however there isn't currently a supported way of doing it.You could use the following unsupported method call to reload the whole form: Mscrm.ReadFormUtilities.openInSameFrame(window._etc, Notes:

This technique could also be written using a plugin - but the advantage of using a Synchronous workflow is that the logic that determines the stage can be easily changed without re-compiling code. You can use the same technique to read the process and stage name so that you can make a decision using the current position in the process. I've included a sample of this too in the download You can download the sample code from here -