4

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

user3255061
  • 1,757
  • 1
  • 30
  • 50
  • Seems somewhat related to http://stackoverflow.com/questions/34261631/how-to-redraw-tables-using-angular-ui-tabs-and-ui-grid – imbalind Dec 14 '15 at 09:24
  • 1
    I've edited your plunker to show what I meant: http://plnkr.co/edit/bYEepuvm6Pu4bvAUPzZe?p=preview – imbalind Dec 14 '15 at 19:44
  • Thanks a lot for the effort, but that plunker doesn't work either if one changes the viewport: http://imgur.com/oAK5VnG. – user3255061 Dec 15 '15 at 17:44
  • There was a typo in my code: `if (flag === 'test1') {` should have been `if (flag === 'test') {`. [Here](http://plnkr.co/edit/bYEepuvm6Pu4bvAUPzZe?p=preview) I fixed it. Give it a try. – imbalind Dec 16 '15 at 08:33
  • No, unfortunately still the same issue (even with the plunkr). Did you try to resize your window? Could that be a browser issue somehow? – user3255061 Dec 16 '15 at 13:44
  • 1
    I tried with both Chrome and Firefox (both up to date) and it works even after resizing. What browser are you using? Are you sure you tried the last version: http://plnkr.co/edit/bYEepuvm6Pu4bvAUPzZe?p=preview ? – imbalind Dec 16 '15 at 14:10
  • Thanks a lot for your help, I really appreciate it. Didn’t wait long enough for the grid to render, your plunker works - unfortunately my code still doesn’t (see update). – user3255061 Dec 19 '15 at 12:04
  • I think you'd better close this answer and open another one since the problem now is different then what the title says – imbalind Dec 19 '15 at 12:22
  • Guess I don't have enough reputation yet to close a question, so I have to leave it open. Thanks for the suggestion though. – user3255061 Dec 21 '15 at 18:34
  • I meant you can accept the answer since it actually solves your original problem – imbalind Dec 21 '15 at 20:39
  • True. Thanks for your help again. – user3255061 Dec 22 '15 at 12:53
  • No luck in Internet Explorer 11 – bhantol Apr 01 '16 at 19:24

4 Answers4

3

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.

imbalind
  • 1,182
  • 6
  • 13
0

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.

bhantol
  • 9,368
  • 7
  • 44
  • 81
0

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

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

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();
    });
});
SzilardD
  • 1,611
  • 2
  • 22
  • 40