11

I have a dynamic tabset that generates the tabs from an array which starts out blank. When I add a new item to the array it appears as a new tab. I want the last added tab to be the active one. I set the active index every time I add an item to the array

HTML:

<uib-tabset active="activeTabIndex">
    <uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}">Some content</uib-tab>
</uib-tabset>

JavaScript:

$scope.activeTabIndex = 0
$scope.tabs = [];

$scope.addTab = function() {
    var newTab = {  title: 'Tab ' + ($scope.tabs.length + 1) };
    $scope.tabs.push(newTab); 
    $scope.activeTabIndex = ($scope.tabs.length - 1);
    console.log($scope.activeTabIndex);
};

Here's the Plunk for the full source code of the demo: https://plnkr.co/edit/TX6ek4R62AfM2zUXcoC3?p=preview

The problem is it seems to be working with odd number of tabs only. Here's what I mean:

On initial load it looks like this:

enter image description here

After I add a new tab it shows the active one correctly:

enter image description here

When I add another one nothing becomes selected and activeTabIndex variable becomes undefined:

enter image description here

And on the 3rd one it starts working again:

enter image description here

So for even active index numbers (0, 2) it works fine. But somehow instead of Acitve Index: 1 it shows blank and doesn't set the active tab. I write the variable to console and it displays all the values correctly.

Any help/pointers/ideas are welcome.

Thanks.

Volkan Paksoy
  • 6,727
  • 5
  • 29
  • 40

2 Answers2

17

According to docs:

active (Default: Index of first tab) - Active index of tab. Setting this to an existing tab index will make that tab active.

Ensure the tabs array contains the active one, I think you should add a $timeout there:

      $scope.addTab = function() {
        var newTab = {  title: 'Tab ' + ($scope.tabs.length + 1) };
        $scope.tabs.push(newTab); 
        $timeout(function(){
          $scope.activeTabIndex = ($scope.tabs.length - 1);
        });
        console.log($scope.activeTabIndex);
      };

https://plnkr.co/edit/q4QP7zoB0HXSjn3MplE4?p=preview

huan feng
  • 7,307
  • 2
  • 32
  • 56
  • 2
    Thanks. Timeout seems to do the trick but still cannot understand why it works half the time without it. Any comments on that seemingly odd behaviour? – Volkan Paksoy Apr 05 '16 at 08:10
  • Good question, I also feel confused why it works for the odd tabs. – huan feng Apr 05 '16 at 08:17
  • 4
    I asked this question on GitHub and the PM of the project responded that similar issues have been reported and they don't support dynamic tabs. Looks like setting the index inside timeout is the officially recommended solution. So I'll accept it as the answer. For the sake of completeness here's the thread I got the response: https://github.com/angular-ui/bootstrap/issues/611 – Volkan Paksoy Apr 06 '16 at 05:45
  • Thanks for sharing – huan feng Apr 06 '16 at 05:56
0

I had the similar problem, But a little more Complex. I loaded my dynamic tabs from API, and I had one static tab and the rest were dynamic.

<uib-tabset active="activeTabIndex" ng-if="showTabs">
    <uib-tab heading="Static Heading">Static content</uib-tab>
    <uib-tab data-ng-repeat="tab in tabs" heading="{{tab.title}}">Some content</uib-tab>
</uib-tabset>

I used two variables with default values:

$scope.showTabs = false;
$scope.activeTabIndex = 0;

First, I loaded my dynamic tabs from API, Then in the success callback, I specified the value of activeTabIndex from tabs array. Then I changed the value of showTabs to true.

I shared it, just hope it can help more people with this case.

Roham Rafii
  • 2,929
  • 7
  • 35
  • 49