0

I have tabs, for which some are dynamically shown with ng-show. The problem is that if the first tab is not shown, then the second tab should be the active tab. But it is not working this way. It seems the first tab is still active, causing the tab 1 content to be in the tab 2.

enter image description here

What I need is the following, when the tabs are first loaded

enter image description here

In the code below if I set the active="1" for the ui-tabset, then it works as expected

<uib-tabset active="1">

But I can't do this, as this needs to be dynamic. The first tab may or may not be shown. I tried to use a binding value (as shown in the code below) for the active attribute, but that doesn't work. It still has the same result as the first image above.

I have the following MCVE (also Plunker)

html

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
    <script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.3.2.min.js"></script>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
  </head>
  <body ng-app="exampleApp">
    <div ng-controller="TabsDemoCtrl">
      <uib-tabset active="initialActive">
        <uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" ng-show="tab.show" 
                 active="tab.active" index="$index">
          {{tab.content}}
        </uib-tab>
      </uib-tabset>
    </div>
  </body>
</html>

script

angular.module('exampleApp', ['ui.bootstrap'])
  .controller('TabsDemoCtrl', function($scope) {

    $scope.tab1Show = false;
    $scope.initialActive = $scope.tab1Show ? "0" : "1";

    $scope.tabs = [
      { title: 'Tab 1', content: 'Tab 1 Content', active: false, show: $scope.tab1Show },
      { title: 'Tab 2', content: 'Tab 2 Content', active: true, show: true },
      { title: 'Tab 3', content: 'Tab 2 Content', active: false, show: false },
      { title: 'Tab 4', content: 'Tab 2 Content', active: false, show: true },
      { title: 'Tab 5', content: 'Tab 2 Content', active: false, show: true }
    ];

  });

EDIT

There are typos in the content of the tabs, but it doesn't really affect the question and the results, as the question is really only concerned with the tab 2 content, which is correct.

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720

2 Answers2

2

use ng-if instead ng-show Plunker

  <uib-tabset active="initialActive">
    <uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" index="$index" ng-if='tab.show'>
      {{tab.content}}
    </uib-tab>
  </uib-tabset>
aseferov
  • 6,155
  • 3
  • 17
  • 24
  • Do you have an explanation for what the difference is in this case; why one works and the other doesn't? – Paul Samsotha May 15 '16 at 06:39
  • actually it both can be works. As @SSH said in your `$scope.tabs` all content `Tab 2 Content` – aseferov May 15 '16 at 06:44
  • Copy and paste error, but that's not the problem as the tab content for the first and second tab are the only ones we're concerned with, and those are correct – Paul Samsotha May 15 '16 at 06:48
  • Hi! Please I have 3 tabs in a modal that I use and open for the add and edit mode. In the add mode the tabs 2 and 3 are disabled but they are enabled in the edit one. The problem is that when I click the tab2 for example in the edit mode then I open the modal in the add mode, I set the first tab to be active and it works but the showed content is not the content of tab1. It shows me the content of the tab2. How can get the right content? – Ne AS Dec 26 '16 at 14:35
1

Use ng-if instead of ng-show. ng-show only hides other tabs(the ones before tab 2), while actually they are already rendered into the dom.

The first tab that gets rendered into the dom is the active one according to the implementation of ui-tabs. So, the first rendered li[tab item] is the active one and a css class active is applied to that- which creates the nice border for active state like below.

enter image description here

When you used ng-show, that item got created, got applied the active css class, and then it became hidden because of ng-show(which applied a css class on that element that does nothing but hides it by applying the rule display: none !important).

ng-if makes sure the element is not getting rendered into the dom, so the first element that gets rendered is tab 2 and there's no other elements before it, so logically- active class gets attached to it and you see the expected border and designs.

Munim
  • 2,626
  • 1
  • 19
  • 28