angular-ui / ui-grid

UI Grid: an Angular Data Grid
http://ui-grid.info
MIT License
5.39k stars 2.47k forks source link

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

Open viveleroi opened 2 years ago

viveleroi commented 2 years ago

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):

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.

viveleroi commented 2 years ago

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);
        }
    }
})]);