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
// 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
Filed under: CRM 2013, Javascript