I managed to find a solution by implementing methods that dynamically change the container height. In the controller, I first initalize variables that will be used later in JS and the template using ng-style:
//===================================================
// Initalize height that will be altered later based
// on tree expand/collapse events
//===================================================
var row_height = 30; // use this to set height everywhere
$scope.height = row_height;
$scope.height_px = row_height + 'px'; // used in template with ng-style
Then while initialize the tree view grid options, one can reference row_height. We also add the logic to add or deduct height based on rowExpanded
and rowCollapsed
events in the options:
$scope.gridOptions = {
rowHeight: row_height,
enableSorting: true,
enableFiltering: false,
//.....continue other options.....
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
// Add container height for row expanded
$scope.gridApi.treeBase.on.rowExpanded(null, function(row) {
addHeight(row.treeNode.children.length);
});
// Deduct container height for row collapsed after considering
// all child node expanded state
$scope.gridApi.treeBase.on.rowCollapsed(null, function(row) {
// get number of children that are already expanded
var count = row.treeNode.children.length;
for(var i=0; i < row.treeNode.children.length; i++) {
count += getChildCount( row.treeNode.children[i]);
}
deductHeight(count);
});
}
}
We then add the methods to controller that are needed for addHeight()
, deductHeight()
and getChildCount()
to work:
// Method to add height of container dynamically based on number of rows
var addHeight = function (num_rows) {
$scope.height += num_rows * row_height;
$scope.height_px = $scope.height + 'px';
};
// Method to deduct height of container dynamically based on number of rows
var deductHeight = function (num_rows) {
$scope.height -= num_rows * row_height;
if($scope.height <= 0) {
$scope.height = row_height;
}
$scope.height_px = $scope.height + 'px';
};
// Method to get count of expanded child rows for a given node (used recursively)
var getChildCount = function (node) {
var count = 0;
if(node.state == 'expanded') {
// change the state to collapsed for all child nodes
node.state = 'collapsed';
count += node.children.length;
for(var i=0; i < node.children.length; i++) {
count += getChildCount(node.children[i]);
}
return count;
} else {
return 0;
}
};
Notice that we recursively get node count when we collapse a node. We also change the state of sub-nodes to collapsed so that the height is calculated correctly the next time.
Finally in the template, we need to reference the $scope.height_px which gives the dynamic height for the container. We do this by setting ng-style="{ 'height': height_px }"
as follows:
<div id="gridTree-1" ui-grid="gridOptions" class="grid" ui-grid-tree-view ui-grid-auto-resize ng-style="{ 'height': height_px }"></div>
One problem that I encountered after this was that the mouse scroll stopped working when it was placed on top of the grid. This problem apparently has a solution as suggested here. However, the actual problem relates to disablement of scroll functionality in ui-grid.js
. In version 3.1.1 line 2721 reads event.preventDefault();
. I had to comment this line out for the scroll to work normally again.