user3255061
user3255061

Reputation: 1815

Ui-grid disappears in angular-ui-tab

I've ui-grids in angular-ui-tabs, they are inside an ng-if to avoid rendering issues. If there is more data and the grid goes into scrolling mode, the data disappears completely when clicking the tabs. I believe this is an ui-grids-bug - can anyone help me here?

Plunkr: http://plnkr.co/edit/kDlS4zEPE0A0DrUHn0CJ?p=preview

I'm not entirely sure, but maybe the viewport/size of browser window has an effect.

Code is as one would expect:

<uib-tabset justified="true">
    <uib-tab heading="tab" select="setTab('test')">
        <div class="row">
            <div class="col-md-12" ng-if="test">
                <div id="grid1" ui-grid="{ data: myData }" class="grid">
                </div>
            </div>
        </div>
    </uib-tab>
    <uib-tab heading="tab" select="setTab('test2')">
        <div class="row">
            <div class="col-md-12" ng-if="test2">
                <div id="grid2" ui-grid="{ data: myData2 }" class="grid">
                </div>
            </div>
        </div>
    </uib-tab>
</uib-tabset>

enter image description here

Update:

I implemented an $interval as described here. Unfortunately it doesn't work - here is the plunkr: http://plnkr.co/edit/1d2UTOMl3bvtYHr7muTf?p=preview.

Not entirely sure if I implemented it right though, I did

$scope.myData = {
    onRegisterApi: function (gridApi) {
        $scope.gridApi = gridApi;

        // call resize every 200 ms for 2 s after modal finishes opening - usually only necessary on a bootstrap modal
        $interval( function() {
            console.log('in');
            $scope.gridApi.core.handleWindowResize();
            }, 10, 500);
        },
data: [....

and in the HTML

<div id="grid1" ui-grid="myData" class="grid"></div>

What's very strange: In my local code it's always the second tab that disappears, never the first (the first is rendered properly). And the second tab always just shows the first 4 items - so it's not entirely gone. This all looks like I messed up my code on first sight, but if I switch the grids (put the grid from tab 2 into tab 1 and vice versa) it's again the first one that renders perfectly and the second one that just shows the first four items.

Update 2:

I implemented @imbalind 's solution (thanks again), looks like I’m having some other issues here. I assume there is some other library conflicting and it appears to me that ng-repeat gets somehow terminated in the second grid. The ui-grid-canvas div-container is actually very large, but empty except for the first four items.

Tried hard to investigate with other library it might could be, but I can’t find out. Guess I’ll have to work around with ng-views and “faking” the tabs, although it’s ugly.

enter image description here

Upvotes: 4

Views: 4180

Answers (4)

SzilardD
SzilardD

Reputation: 1751

The issue for me was with a grid that is inside a tab. The tab is rendered only when it is clicked on, so the grid is being initialized before the layout and because of this the rows aren't being shown.

The tab and grid are in different directives.

The tab component has a select event called when the tab is selected:

<tabset>
  <tab select="onTabSelected()"></tab>
</tabset>

Using this event, I emitted another event

$scope.onTabSelected = function () {
   $rootScope.$broadcast('tabSelected');
}

Which is processed in the directive that initializes the grid, and there I call handleWindowResize as described in other solutions.

$rootScope.$on('tabSelected', function () {
    $timeout(function () {
        scope.gridApi.core.handleWindowResize();
    });
});

Upvotes: 0

user9534295
user9534295

Reputation:

You need to set scroll position after handleWindowResize() like below :

$scope.gridApi.core.handleWindowResize();    
$scope.gridApi.core.scrollTo($scope.data[0], $scope.columnDefs[0])

Upvotes: 0

bhantol
bhantol

Reputation: 9616

Use css: visibility: hidden instead of ng-show or ng-if which is what bootstrap tabs use. Basically do away with those tabs. Works fine in IE 11+ also. No need to trigger refresh etc.

Solution is in this plunkr.

Upvotes: 0

imbalind
imbalind

Reputation: 1182

This problem is quite known (even though only referred to uib-modal inside of docs) and inside this tutorial they explain how to address it: you should add a $interval instruction to refresh the grid for some time after it's updated in order to let the tab take its time to load and render.

The code should be as follows:

$scope.tabs[0].gridOptions.data = data; 
$interval( function() {
  $scope.gridApi1.core.handleWindowResize();
}, 10, 500);

Where gridApi1 are created inside of a regular onRegisterApi method.

You can take a look at the code in the tutorial to get a better understanding if needed.

Upvotes: 3

Related Questions