CRM 2013 – Disabling a subgrid

This blog post will look at possible ways to disable subgrids in CRM 2013.  I had a requirement if a user made a case restricted then the case couldn’t be linked to any other cases.

Requirements

  • On the case form we had functionality to select a parent case and a subgrid to add child cases.
  • Case had a restricted bool field
  • Restricted cases could not link to any other cases

If the user set restricted to Yes I had to disable the subgrid and the case lookup, e.g. stop the restricted case from being linked

Disabling the case lookup field was was straightforward

  
Xrm.Page.getControl(fieldName).setDisabled(true);
	

Frustratingly for me subgrid control does not have a setDisabled method, this means disabling the subgrid would not be as straightforward.

Disabling a sub grid

This is a different story, a story with twists, frustration

An unsupported way

http://www.magnetismsolutions.com/blog/paulnieuwelaar/2012/02/28/Disable_Subgrids_with_Javascript_in_Dynamics_CRM_2011.aspx

  
// Disable a subgrid on a form
function disableSubgrid(subgridName) {
document.getElementById(subgridName + "_span").disabled = "true";
}
	

I’m not going to consider putting in unsupported changes because if you do then Microsoft will unsupport your customizations.  This probably doesn’t sound like much of a threat but if you find a bug with out of the box functionality Microsoft won’t even look at your customizations due to the unsupported code.  When the customer then finds out they have no Microsoft support because of your code.

Why you shouldn’t put unsupported customizations in Microsoft Dynamics CRM

From the Hosk Wisdom page 🙂

Don’t even think about making unsupported changes in CRM because Microsoft will un-support your CRM if they find out – Hosk

Don’t do unsupported CRM customizations, 99.9 percent of the time there is another way.  For the 0.1, tell the customer its unsupported – Hosk

Other Options

If I can’t disable the subgrid (in a supported way), what other options do I have?

Disable buttons on subgrid

Scott Durow the Ribbon Workbench creator has an excellent article on disabling the add new button.  This hiding rule could be set on all the add buttons on the subgrid.

Show or hide the ‘Add New’ button on form sub-grid based on the value on the form

It’s worth reading this article just to look at the image which explains what buttons on the sugrid link to what buttons on the command bar inside the Ribbon Workbench.

In theory this option should work but it would involve setting up enable rules for all the buttons on the subgrid.

Hiding and Showing

Hiding and showing sounds like a kids TV show, actually I’m thinking of Show me Show Me

My initial thought was to disable the grid but in CRM 2013 sub grid doesn’t have a setDisable, which stopped my plan but looking at the CRM SDK I can see subgrids control does have a setVisible.

This line of supported code will hide the subgrid 

Xrm.Page.ui.controls.get(controlName).setVisible(false);

This shows it again

Xrm.Page.ui.controls.get(controlName).setVisible(false);

The code above worked and it did hide the subgrid, the problem I had was it looked odd because it left a big blank white space where the sub grid was hiding (not very well).

The other problem is sub grids load asynchronously.  I needed my code to work on the form OnLoad event but when it came to hiding the the subgrid it was loaded yet and would throw an error.

To get round this error, I would need to wait until the subgrid had been loaded, so I could subsequently hide it (which doesn’t seem right when I say that out loud)

I created this code to wait until the subgrid is loaded.

  function ShowSubgrid(show) {
        var Subgrid = Xrm.Page.ui.controls.get("ChildCasesGrid");

        if (Subgrid == null) {
            setTimeout(function () { ShowSubgrid(show); }, 2000);
            //if the grid hasn’t loaded run this again when it has
            return;

        } else {
            if (show) {
                ShowControl("ChildCasesGrid");
            } else {
                HideControl("ChildCasesGrid");
            }
        }
    }
	

This works but I don’t like having wait’s in code, particularly in a form load where you don’t want to add an extra lines running on a form load which usually takes a while and the form load performance is extremely visible to a user.

I am of the opinion to avoid waits in the code at all costs, if you have a wait in the code you have a bug/problem waiting to happen.  Most of the time its worth the effort to find an alternative solution and reduce the complexity of your code.

A wait in code is similar to seeing +1 in some code.  The code is working round a problem rather than resolving the cause.

When considering form loads in CRM, it’s probably comparable to the frustrating time it takes for a computer to boot up in the morning.  The time may only be a short amount of time but it feels about four times as long in real time.

Whilst a form is loading the user has nothing to keep them occupied so the time feels longer, try to keep forms loads as quick as possible.  Here is a blog post I wrote on performance issues

CRM 2011/2013 Investigating CRM Form Performance issues

QUICK BREAK TO LOOK AT CRM 2015 SP1 new GridControl stuff

Looking at the CRM SDK form events page, initially it loads the latest page for CRM 2015 and I noticed CRM 2015 SP1 has a new special Subgrid OnLoad event.

There is a new page Write scripts for subgrids, there is now a new GridControl and you can look Grid objects and methods to see the new cool things you can do

The Grid Onload method is cool but there are some other interesting methods I noticed

The grid has

  • getRows
  • getSelectedRows
  • getTotalRecordCount

From the Grid you can get do a getRows and from here there are some great helper methods in the GridEntity

  • getEntityName
  • getEntityReference
  • getId
  • getPrimaryAttributeValue

and other stuff which you should go and check out yourself

Back to CRM 2013 subgrids

After some developer brainstorming I decided to try putting the subgrid into a section.  The advantages of this is you can hide/show a section without having to wait for the form to load.

Another advantage is when you disable a section it hides itself much better, the form acts as if it wasn’t there at all, unlike hiding the subgrid which leaves a white space the same size as the subgrid.

To hide or show a subgrid you have to toggle the visible flag using the setVisible method

Hide

Xrm.Page.ui.tabs.get("tabName").sections.get("sectionName").setVisible(false);

Show 

Xrm.Page.ui.tabs.get("tabName").sections.get("sectionName").setVisible(true);

Plugin Option

Maybe the most straight forward to resolve this issue is to have a plugin which is triggered on change of parentCase field.  When setting this you could check to see if the child or parent case is a restricted case and throw a pluginException

Conclusion

The blog’s title is about disabling a subgrid but the goal was to stop restricted cases from being linked.

The benefit of Javascript customizations is they are instant because the code works on the client side.  Plugins are server side, so their is a delay in capturing and responding to the changes.

Javascript can often offer a better user experience because CRM developers can react instantly to changes in values and hide/disable fields.

Server side changes are less responsive and cannot guide the user in the same way Javascript validation code can but has to catch the values and decide whether to roll them back.  Server side validation can be more frustrating to CRM users because they have made the changes, only to find them being rejected.

In this scenario the plugin/server changes are in one place, where there are lots of Javascript code changes to do the same thing.

A key skill of a CRM developer is selecting the right customization for the right job

3 thoughts on “CRM 2013 – Disabling a subgrid

  1. Anuj Govil October 3, 2017 / 2:27 pm

    You are a champ man…. Thank a lot for helping me out here. 🙂

    Like

  2. Michael Blackburn February 14, 2018 / 6:47 pm

    I usually counsel my clients to consider doing both client-side script and server-side plugins, especially if the action is security-sensitive. I like to say “if it can be done with JavaScript, it can be undone with JavaScript.” If a user isn’t supposed to update a field once the entity hits a certain status, I say you both disable the field in the UI, AND add a plugin that prevents the update with the same rules. This way, you get the user guidance and smooth experience of JavaScript, but you also get the assurance that this policy will be enforced, even if:
    * The user manipulates the page using JS console or bookmarklets
    * a new form is created without your updates,
    * the data is updated in some other integration (via WebAPI or SOAP endpoint),
    * the user Exports & Imports the data.

    This is a lot more work, but depending on the client, is likely a good idea. At the very least, I make sure the JS approach is communicated and documented as a “convenience” or “guidance” functionality, and explicitly identified as not a “security” measure.

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.