angular-ui/ui-grid

[BUG] Grid width/height broken when grid is in an inactive ui-bootstrap tab

Opened this issue · 1 comments

Describe the bug
We recently updated from 4.0.10 to 4.11.1. Both have this problem but the result is slightly different. 4.0 wouldn't show any grid data. 4.11 shows the header and maybe 1 grid row but neither the width or height are 100% of their parent until you mouse over the grid or trigger a resize.

Once we do trigger a resize, it's correct. However, when we tab away and come back, the grid "flashes" back to the broken form, and then back to the correct size.

To Reproduce
Steps to reproduce the behavior:

  1. Put a grid inside a ui-bootstrap tab that isn't shown right away
  2. Load the page
  3. Click to the tab with the grid inside

Expected behavior
The grid should take up the available space.

Screenshots
chrome_5Wrjbj5aMc

Desktop (please complete the following information):

  • Windows 10, Chrome 106

Additional context
Looking into the ui-grid code, viewPortHeight is NaN because it's trying to do math with grid.gridHeight, yet getWidthOrHeight is returning 100%, which is a string. I assume the problem here is the grid isn't visible when it first runs height calcs.

If anyone else has this issue, we wrote a hacky directive to fix this. Add the attribute to any uib tabset element and this will call the grid' resize function after tab change:

directive('uibTabGridAutoResize', ['$timeout', $timeout => ({
    require: 'uibTabset',
    restrict: 'A',
    link: (scope, $element, attrs, tabsetCtrl) => {
        const { select } = tabsetCtrl;
        tabsetCtrl.select = function() {
            // Delay our DOM query because the active class needs to switch
            $timeout(() => {
                // Look for a ui-grid element (not .ui-grid itself, the scope isn't what we expect).
                const $uiGrid = $element.find('> .tab-content > .tab-pane.active .ui-grid-contents-wrapper');
                $uiGrid.each(function() {
                    angular.element(this).scope().grid.api.core.handleWindowResize();
                })
            });

            // Call the original function
            select.apply(tabsetCtrl, arguments);
        }
    }
})]);