Haven’t you ever wondered why the “Activate” button is still visible after you have selected an (already) active record?

2018-05-05 09_30_30-Accounts My Active Accounts - Microsoft Dynamics 365
Both the Activate and Deactivate buttons are visible for a selected active record.

Well, I certainty did. For me, this is a clear example of bad user experience. Having both buttons available makes no sense and it can only bring confusion. In this case it would be better to either show the “Activate” or the “Deactivate” button depending on the status of the selected record. But can we accomplish this kind behavior in Dynamics 365 Customer Engagement? In a supported way? Sure, in this blog post I will show you how.

Conditionally showing a button on a form based on a form value is pretty simple and can be accomplished by using EnableRules and DisplayRules. If you would open a contact record, you would only see the “Activate” or “Deactivate” button depending on the status of the record that is being viewed. Having the same behavior for the selected record on the HomePageGrid or Subgrid on the other hand is a bit more complex and we’ll need a little bit of JavaScript (supported JavaScript, of course).

Tip: Without having you to alter the RibbonDiffXml structure directly (which is very error prone), you can use the excellent tool from Scott Durrow, the Ribbon Workbench.

Conditionally show button based on selected record

JavaScript

Let’s start by creating our custom JavaScript. Create a new JS Web Resource named “contact.commands.enableRules.js”.

2018-05-06 12_10_18-Web Resource_ New - Microsoft Dynamics 365
Creating a new Web Resource

Insert the following code:

var Dynamict_Contact;
(function (Dynamict_Contact) {
    /**
    * All commands from the ribbon
    */
    var Commands;
    (function (Commands) {
        /**
        * Custom Enablerules (RibbonDiffXml)
        */
        var EnableRules;
        (function (EnableRules) {
            var selectedCustomerIsActive;
            var previousSelectedItemId;

            function isSelectedContactActive(selectedEntityTypeName, firstSelectedItemId, primaryControl) {
                var stateCodeAttr = 'statecode';
                if (firstSelectedItemId == null)
                    return;
                //Selected a different item in the Grid
                if (previousSelectedItemId !== firstSelectedItemId) {
                    previousSelectedItemId = firstSelectedItemId;
                    //Retrieve the value

                    Xrm.WebApi.retrieveRecord(selectedEntityTypeName, firstSelectedItemId.replace(/[{}]/g, ""), "?$select=" + stateCodeAttr).then(function success(result) {
                        selectedCustomerIsActive = !result[stateCodeAttr];
                        primaryControl.refreshRibbon();
                    },
                        function (error) {
                            console.log(error.message);
                        }
                    );
                }
                else {
                    return !selectedCustomerIsActive;
                }
            }
            EnableRules.isSelectedContactActive = isSelectedContactActive;
        })(EnableRules = Commands.EnableRules || (Commands.EnableRules = {}));
    })(Commands = Dynamict_Contact.Commands || (Dynamict_Contact.Commands = {}));
})(Dynamict_Contact || (Dynamict_Contact = {}));

The JavaScript code will be triggered as soon as the Ribbon is loaded or the selected record has changed. The function should return either true (= show the button) or false (= hide the button). The code should be fairly self explanatory, so I’m not going into detail.

Ribbon Workbench

Next, we have to create a new EnableRule for the “Activate” button on the HomepageGrid by using Ribbon Workbench. Modifying buttons that came out of the box  requires you to right click the button and choose “Customise Command”.

2017-04-23 11_44_03-Ribbon Workbench 2016
Customize an existing out of the box commands

Add a new Enable Rule (1) and give it a meaningful name (ex: new.contact.EnableRule.RecordIsNotActive). Next, we add a CustomRule (3) to our Enable Rule. This CustomRule will point to our previously uploaded JavaScript.

2018-05-06 12_13_24-XrmToolBox for Microsoft Dynamics CRM_365 CE (v1.2018.4.22)FunctionName = Dynamict_Contact.Commands.EnableRules.isSelectedContactActive
Library = $webresource:new_contact.commands.enableRules.js

Finally, we will add three CRM Parameters (4) to our CustomRule to identify the selected record and have the correct context. To identify the selected record, we need: SelectedEntityTypeName and FirstSelectedItemId. To get the context, we need the CRM Parameter PrimaryControl.

After we finished creating our Enable Rule, we have to tie it to our command. Select the Mscrm.HomepageGrid.Active command (1), click Add Enable Rule (2) and select our new Enable Rule (3).

2018-05-06 12_19_47-Clipboard

Finally, click “Publish” on the top of the RibbonWorkbench to save our changes:

2018-05-06 12_22_46-XrmToolBox for Microsoft Dynamics CRM_365 CE (v1.2018.4.22)

Results

Next, we can test our result.

  • Scenario A: No record selected: Both the Activate & Deactivate button are not their (OOB behavior – Enable Rule: SelectionCountAtLeastOne)
  • Scenario B: A single inactive record selected: The Activate button is relevant and thus shown.
  • Scenario C: A single active record selected: The Activate button is not relevant and thus not shown.

2018-05-06 12_29_17-Clipboard

Conclusion

As you can see, with a few lines of code you can conditionally show a button based on the selected record in a grid. Implementing this functionality can greatly improve user experience. Please note that we didn’t cover the use case where multiple records were selected.

6 thoughts on “Conditionally show button based on selected record”

    1. In that case I would keep it simple and show both the “Activate” and “Deactivate” buttons. Users potentially want to bulk activate/deactivate records. For this you need to change the code and pass an additional Crm Parameter (SelectedControlSelectedItemCount).

  1. Thank you so much for this detailed tutorial, but i think there a small problem, you need to select twice the record in order to have the best result, else if u select the record once u will may have the unsuitbale button shown.

  2. after testing the solution deeply, i found that it works fine in UI but not in classic interfaces, So i did some resaerch, and i figure out that adding a filter on primaryControl.refreshRibbon() will solve the issue:
    Solution:

    Before : primaryControl.refreshRibbon();

    After :

    if (Xrm.Internal.isUci()){
    primaryControl.refreshRibbon();
    }
    else
    {
    refreshRibbon();
    }

  3. This code is hiding the Activate button for both Active and inactive items. What could be the cause

Leave a Reply