Posted on 28. February 2014

Ribbon Workbench updated - getServerUrl is removed in CRM2013 UR2

With CRM2013 UR2 being released very soon I have made an update to the Ribbon Workbench that you'll be prompted to install by the auto update when you next open the Ribbon Workbench. I strongly advise you to install this update before you install UR2 otherwise the Ribbon Workbench will no longer work, and you'll need to re-download and re-install.

This is because when I updated the Ribbon Workbench for CRM2013 I retained the use of getServerUrl – the update now uses getClientUrl because UR2 has removed getServerUrl altogether.

getServerUrl was deprecated back in CRM2011 with UR12 so it's probably about time it was removed anyways!

Posted on 5. December 2013

Form File->Properties dialog in CRM 2013

One of the lesser known features of CRM 2011 was the File->Properties dialog that you could view on a record form. It would look something like:

This dialog was very useful for finding out the effective permissions of the current user on a particular record but in CRM 2013 it is no longer present in the user interface – but it is still there in the background!

If you used to use this dialog in CRM 2011 I've created a managed solution that provides you with a Properties button on the Command Bar that shows the CRM 2013 version of this dialog.

FormPropertiesButton_1_0_0_0_managed.zip (2.39 kb)
(The usual disclaimer applies)

After installing the solution, you should see a new button in the Command Bar overflow menu:

The dialog looks like this:

The only down side is clicking OK gives the 'Are you sure you want to navigate away from this page' dialog.

Hope this helps.

@ScottDurow

 

Posted on 21. November 2013

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.

 

@ScottDurow

Posted on 24. October 2013

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:

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

Further reading:

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

 

Posted on 20. September 2013

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.

3. 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.

4. 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:

Modern

The control is visible in the Tablet client

Refresh

The control is visible in the Command Bar

Legacy

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

Posted on 6. September 2013

How to restore a hidden button on the CRM 2013 Command Bar

The new Dynamics CRM 2013’s command bar has deliberatly limited space for buttons due to the ‘intentionally constrained’ user interface design. The idea being that if you limit the space for buttons, then designers will be forced to only show those that are absolutely necessary and the user experience will be improved. As result, many of the buttons from the CRM 2011 Ribbon Bar have been removed from the CRM 2013 Command Bar.

The CRM2011 Ribbon Buttons are still there, but hidden using a new RibbonXml Display Rule named 'Mscrm.HideOnCommandBar'. This article shows you how to restore those buttons to the Command Bar that your users absolutely must have using the Ribbon Workbench for CRM2013.

1. Create a solution containing the entities that you wish to restore buttons for. This example uses the ‘Case’ entity, and we are restoring the ‘Connect’ button on the ‘Form’ command bar.
Before customising, the Form Command Bar looks like the following:

You’ll notice that only 5 buttons are shown until buttons are added to the ‘overflow’ menu. The ‘Connect’ button is not here since it was deemed unessential.

2. Open the solution containing the Case entity in the Ribbon Workbench for CRM 2013 and select the ‘incident’ entity if not already selected. You will see by default the Command Bar is selected.
 

3. In order to locate the button we want to restore, click on the ‘Ribbon’ selector to show the Ribbon. This will show the Ribbon Design surface.

4. Select the ‘Form’ ribbon using the dropdown on the top right of the design surface, then select the ‘Connect’ button and Right-Click ‘Customize Command’

5. Locate the Customised Command in the ‘Solution Elements’ tab under ‘Commands’

6.  In the Edit Display Rules dialog, select the ‘Mscrm.HideOnCommandBar’ rule and click the ‘<Remove’ button.

7.  Important: Locate the following Display Rules, and set the ‘IsCore’ property to ‘True’ – this will prevent them from being customised as well:

a.      Mscrm.HideOnCommandBar

b.      Mscrm.CreateConnection

c.      Mscrm.IsConnectionsEnabledPrimary

d.      Mscrm.HideOnModern

8. Important: Locate the ‘Mscrm.FormStateExistingOrReadOnlyOrDisabled’ Enable Rule, and set the ‘IsCore’ property to ‘True’

9. Click ‘Publish’

10 Now when you refresh the Case Form, you will see the Connect button again.

11  You’ll notice that only the default button is shown – so if you use the drop down, you’ll only get the ‘Connect to Another’ option. To enable the ‘To Me’ button repeat the process for the ‘To Me’ button:

Remember to make sure that only the buttons that are really needed are included - the Command Bar has been constrained intentially to give your users the best experience.

@ScottDurow

 

Posted on 7. August 2013

Ribbon ‘XML’ Workbench for Dynamics CRM 2013 with a silent ‘XML’!

After much deliberation and consultation, I have decided to stick with the name 'Ribbon Workbench' rather than rename to CommandBar Workbench. Here are some of the reasons behind this decision:

  1. The Command Bar in CRM 2013 is still defined with RibbonXml, but rendered differently. A DisplayRule is used to exclude buttons from the CommandBar.
  2. The Ribbon is still present on non-refresh entities and in Outlook so it's important to still have support for Ribbon editing.
  3. Since the Ribbon Xml remains unchanged, it's important to understand and differentiate between Tabs/Groups and Layouts.
  4. The Ribbon Workbench is already an established 'brand' than people know about.
  5. So until we have CommandBar XML in a future version of Dynamics CRM – it'll always be the Ribbon 'XML' Workbench with a *silent* 'XML'!

The new version has the following improvements:

  • Dynamic switching between the Command Bar and Ribbon view
  • UI refreshed to match Dynamics CRM 2013
  • Performance Optimisations
  • Support for new Dynamics CRM 2013 schema
  • For those of you with access to the Dynamics CRM 2013 beta - the Ribbon Workbench for Dynamics CRM 2013 beta is available for download here:
    http://www.develop1.net/public/page/Ribbon-Workbench-for-Dynamics-CRM-2011.aspx

    @ScottDurow

    Posted on 29. March 2013

    Asynchronous loading of JavaScript Web Resources after U12/POLARIS

    We all know that UR12/POLARIS was a monumental release for Dynamics CRM what with the new Process Forms and Cross Browser support, but also included were some performance optimisations. One such improvement was a change to the way JavaScript Web Resources are loaded on forms so that they load and execute asynchronously rather than in the order that they were added to the form. The drawback with this optimisation is that it can cause the '..is undefined' script error if you have scripts that depend on other scripts being loaded first.

    This post describes the loading behaviour and some possible solutions.

    How did it work before UR12/POLARIS?

    In my example I have 3 scripts, each dependant on the last. Mscorlib.js is the Script# system library that is needed before any other libraries can be loaded. I'm not talking about code that runs in the 'onload' event of a form but global code that is run after the script has downloaded used to define the prototypes of the objects that are used by the onload code.

    In the Client.js, I might have some Script# generated code that requires a core Script# (ss.IEnumerable) type that is defined in a different script file.

    Xrm.Sdk.DataCollectionOfEntity.registerClass('Xrm.Sdk.DataCollectionOfEntity', null, ss.IEnumerable);

    For this code to run, the mscorlib.js must be loaded and executed first. The same applies if you are using jQuery and jQuery-UI.

    The form definition used to have each script added in order so that they would be added to the 'head' section of the page as follows:

    <head>
    ..
    <script src=”/%7B635001685810000000%7D/WebResources/fdocs_/js/mscorlib.js” type=”text/javascript”></script>
    <script src= /%7B635001685810000000%7D/WebResources/fdocs_/js/Xrm.js” type=”text/javascript”></script>
    <script src=” /%7B635001685810000000%7D/WebResources/fdocs_/js/Client.js” type=”text/javascript”></script>
    ..
    
    

    The resulting load pattern would be something like:

  • The script load/execution would be approximately:

    1. Mscrolib.js downloads and then executes
    2. Xrm.jsd downloads and then executes after mscrolib.js has completed executing since it follows it in the <HEAD> section of the page
    3. Client.js downloads and then executes after Xrm.js has completed executing since again it is added to the <HEAD> section in this order.
    4. The On Load event code then runs when all the scripts have loaded and finished executing

     

     

    What changes with the UR12/POLARIS update?

    Scripts are no longer in the <HEAD> section but are loaded asynchronously via the 'loadScriptAdv' function:

    loadScriptAdv('\x2f\x257B635001707050003339\x257D\x2fWebResources\x2ffdocs_\x2fjs\x2fmscorlib.js', '\x2f\x257B635001707050003339\x257D\x2fWebResources\x2ffdocs_\x2fjs\x2fmscorlib.js', false);
    loadScriptAdv('\x2f\x257B635001707050003339\x257D\x2fWebResources\x2ffdocs_\x2fjs\x2fXrm.js', '\x2f\x257B635001707050003339\x257D\x2fWebResources\x2ffdocs_\x2fjs\x2fXrm.js', false);
    loadScriptAdv('\x2f\x257B635001707050003339\x257D\x2fWebResources\x2ffdocs_\x2fjs\x2fClient.js', '\x2f\x257B635001707050003339\x257D\x2fWebResources\x2ffdocs_\x2fjs\x2fClient.js', false);
    

    The new asynchronous load behaviour results in the OnLoad being run after a smaller wait time since each script can execute without waiting for the preceding ones. This is a good performance gain but causes scripts to fail if the dependant scripts are not loaded at the point of execution.

  • The interesting thing is that this wasn't immediately apparent or was only an intermittent problem because once the scripts are loaded into the browser cache, the execution would usually be in the correct order. I can consistenly reproduce the issue by clearing down the browser cache and then disabling all caching.

    Ribbon JavaScript

    It's been a common technique to add dependant libraries to Ribbon Commands by adding them as Command Actions with a function of 'isNaN'

    <Actions>
    <JavaScriptFunction Library=”$webresource:mscorlib_crm.js” FunctionName=”isNaN”/>
    <JavaScriptFunction Library=”$webresource:xrm.js” FunctionName=”isNaN”/>
    <JavaScriptFunction Library=”$webresource:RibbonCommands.js” FunctionName=”someCommand”/>
    </Actions>
    
    

    It seems that the same issue exists with these libraries since they are loaded in an asynchronous fashion.

    Solutions

    Unfortunately, any solution that uses depending scripts in this way has to be updated – and like with all things, the right solution depends on your specific case.

    1) All script in a single library

    By far the simplest solution is to put all of your scripts into a single file in the correct order.

    I didn't' settle for single script option for the following reasons:

    1. A single script is harder to maintain
    2. Common libraries can't be shared between solutions
    3. All code must be downloaded on first use, rather than only downloading what is required at the time.

    2) RequireJs or HeadJs

    There are some good JavaScript loading libraries out there such as RequiresJs or HeadJs. These libraries allow you to dynamically load dependant script before you execute code that needs them.
    Gayan has an example of this technique on his blog. Maarten also has a good tutorial on his blog.

    I didn't settle for the RequireJs/HeadJs option for the following reasons:

    1. It requires you to manually set the Cache key to ensure that scripts are not downloaded every time they are needed
    2. It completely bi-passes the Dynamics CRM script loading mechanism in an 'unsupported' way
    3. There is some possibility that a backward compatibility option may be added into a future release (I'm ever the optimist!). Adopting this approach would make it harder to revert back to the standard script registration approach.

    3) Manually wait for required libraries to load

    The approach I took was to build a simple wait function to wrap code in that prevented execution until the required scripts had loaded. Each time a script completes, it adds its name to a semaphore array that is waited on by other libraries. The result is much the same as before UR12:

  • The difference here is that the scripts start executing as soon as they are loaded, but then wait using setTimeout until the required scripts have completed. The code will work on pre-UR12 systems as well, but because the wait is unnecessary, the code will simply execute the script without checking dependancies. setTimeout is used to release control to other scripts because Javascript is single-threaded.

    The Code

    Each script that has dependencies must be wrapped in the following:

    waitForScripts("client",["mscorlib", "xrm",],
    function () {
    //Original Code goes here
    });
    

    The first parameter provides the name of the current script, and the array is the list of scripts that must be loaded first.

    So in the Xrm.js library, you would wrap it in:

    waitForScripts("xrm",["mscorlib"],
    function () {
    //Original Code goes here
    });
    

    Each script must also include the waitForScript function at the bottom:

    function waitForScripts(name, scriptNames, callback) {
        var hasLoaded = false;
        window._loadedScripts = window._loadedScripts || [];
        function checkScripts() {
            var allLoaded = true;
            for (var i = 0; i < scriptNames.length; i++) {
                var hasLoaded = true;
                var script = scriptNames[i];
                switch (script) {
                    case "mscorlib":
                        hasLoaded = typeof (window.ss) != "undefined";
                        break;
                    case "jquery":
                        hasLoaded = typeof (window.jQuery) != "undefined";
                        break;
                    default:
                        hasLoaded = window._loadedScripts[script];
                        break;
                }
                allLoaded = allLoaded && hasLoaded;
                if (!allLoaded) {
                    setTimeout(checkScripts, 10);
                    break;
                }
            }
            if (allLoaded) {
                callback();
                window._loadedScripts[name] = true;
            }
        }
        // Only check for async loading of scripts if later than UR12/POLARIS
        if (typeof(APPLICATION_FULL_VERSION)!='undefined' && parseFloat(APPLICATION_FULL_VERSION.replace('5.0.',''))>9690.2835) {
    	setTimeout(checkScripts, 0);
        }
        else {
    	callback();
            window._loadedScripts[name] = true;
        }
    }

    Script# 'Script.template'

    I almost exclusively use Script# in my Dynamics CRM projects. What made this solution really work well for me was that I just include the code in the Script.template file to wrap the '#include[as-is] "%code%"'. The beauty is that I can now forget it's there and it just gets minified along with the rest of the code when deployed.

    This issue has affected a number of people I know, and I'm sure it'll start to become more of an issue as people start to upgrade to the latest Rollup. If you have any suggestions/comments, please let me know.

    The code was originally posted by me in the MSDN forums:

     http://social.msdn.microsoft.com/Forums/en-US/crmdevelopment/thread/fdca4779-e866-4e51-bab9-97a159f9cd37

     

    UPDATE: This issue is now fixed in UR15 -http://support.microsoft.com/kb/2843571

    @ScottDurow

    Posted on 19. February 2013

    App/Command Bar Workbench for Dynamics CRM 2013

    The present roadmap for Dynamics CRM has the next version (Dynamics CRM 2013 possibly) sporting the new 'modern' UI throughout. An automatic upgrade path from Dynamics CRM 2011 forms customisations and ribbons will be provided - and it's likely to use a similar RibbonXml like schema under the hood. With this in mind I've done some re-imagining of what the Ribbon Workbench might look like by the end of the year.

    Introducing the App Bar Workbench for Dynamics CRM 2013

  •  

    Exciting times are ahead :)

    @ScottDurow

    Posted on 2. February 2013

    Adding Auto Refresh to Dashboards

    This post shows you how to set up a CRM2011 Dashboard 'auto-refresh' feature using the Ribbon Workbench in 10 easy steps (well…11 if you count clicking publish at the end!).

    We will add an auto refresh function to the 'EnableRule' of the Dashboard refresh button that schedules a refresh using the 'setTimeout' function. The EnableRule is called when the dashboard page is first displayed to check if the Refresh Button should be enabled. We schedule the refresh, and then return true to ensure the button is still enabled. This technique can also be used to add JavaScript to areas of CRM 2011 that are not form based.

    Let's get started:

    1) Create a new solution and add the Application Ribbon to it (Client Extensions->Add Existing->Application Ribbon).

    2) Create a new web-resource named 'RefreshRibbon.js' (or something similar)

    Add the following JavaScript to it:

    var AUTO_REFRESH_INTERVAL=30000;
    /// Schedule the first refresh if we havn't already
    function autoRefreshDashboards() {
        var topWindow = window.top;
        if (typeof (topWindow['refreshRegistered']) === 'undefined') {
            window.setTimeout(autoRefreshTimeoutCallback, AUTO_REFRESH_INTERVAL);
            topWindow['refreshRegistered'] = true;
        }
        return true;
    }
    // Refresh the dashboards and schedule the next refresh
    function autoRefreshTimeoutCallback() {
        try {
            Mscrm.DashboardRibbonActions.refreshDashboardPage();
            window.setTimeout(autoRefreshTimeoutCallback, 30000);
        }
        catch ($e1) {
            // Perhaps the dashboards are no longer loaded. and we are on a different page
        }
    }
    
    

    Note: You can change the refresh interval using the 'AUTO_REFRESH_INTERVAL' value which is in milliseconds (30000=30 seconds)

    Your solutions should now look something like:

  • 3) Open the Ribbon workbench, and load up your new solution.

    4) Select the 'Application Ribbon' in the 'Entities' panel if not already, then select the 'Dashboards' tab in the Design surface (be sure to select 'Dashboards' and not 'Dashboard')

    5) Right click on the 'Refresh All' button and click 'Customise Command' (Not Customise Button)

  • 6) Locate the 'Mscrm.DashboardTools.RefreshCommand' command in the 'Commands' section of the 'Solution Elements' panel. Right click, and select 'Edit Enable Rules'

    7) In the Enable Rules dialog click '+Add New' and then select 'Add Step', before selecting 'Custom JavaScript Rule'

    8) In the Enable Rule properties, set:

    FunctionName: 'autoRefreshDashboards'

    Library : Click the lookup button and select the 'RefreshRibbon.js' (If you don't see it, then you forgot to add the javascript webresource you created above to the solution you loaded into the Ribbon Workbench)

    9) Click OK, and OK again.

    10) In the 'Solution Elements' panel, expand the 'Enable Rules' and select 'Mscrm.IsDashboardSelected'. In the properties panel, set 'IsCore' = True.

    This ensures that this rule is not customised in our solution since we only need to customise the Command to add the new enable rule.

    11) Click Publish Solution

    And you're done! This will work both in the Web Browser and the Outlook client. It is important that you remember that auto-refreshing dashboards could place more load on your server if lots of users leave the dashboards open all day!

    Until next time…

    @ScottDurow