A current project contains a form with a variable number of tabs. Each tab contains a subgrid. It is unlikely that more than 50% of the subgrids will have rows. Displaying the empty tabs creates a sub-optimal user experience that requires considerable scrolling. Consider the following form:
There are two subgrids in this example. The first has a single row and the second (outlined in red) is empty. The reasonable solution is to hide all tabs that have empty subgrids by setting the visibility of each tab in the form OnLoad event. Obviously, the user will no longer be able to add rows to an empty subgrid. In this case a “New SOAP” button will suffice.
Hiding the Grid
This of course is the simple part.
Xrm.Page.ui.tabs.get("PhysicalExaminationsTab").setVisible(rowCount > 0);
Once the rowCount is assigned the visibility is set accordingly.
Getting the Row Count
The first obstacle is the limitations of the Xrm Page control object. Although the subgrid control can be retrieved it does not expose functions to return information such as the row count. The solution is using standard JavaScript.
var exams = document.getElementById("PhysicalExamsGrid");
var rowCount = exams.control.get_totalRecordCount();
Where is the Subgrid?
Now it gets challenging. There are several posts for CRM 2011 that implement the setTimeout function and check the presence and status of the subgrid control prior to requesting the row count.
This causes an endless loop in CRM 2013 because the subgrid is never accessible. After confirming that my code was correct I investigated CRM 2013 specific posts. According to one post CRM 2013 does not expose subgrids in the OnLoad event.
The bottom line is subgrids load after the OnLoad event fires which means the setTimeout function will not work. It simply prevents the OnLoad event from completing. The author of this post employed the JavaScript setInterval function which, unlike setTimeout, schedules a function and allows the OnLoad event to complete.
Implementing this concept provided a clean solution.
Code
This is the code that successfully implements the desired behavior:
This code could be refactored so that it loops through all subgrid controls instead of calling a separate function for each. This approach was used so that specific subgrids will remain visible regardless of the row count.