5

I'm working with angular js and bootstrap 3 and my app works like ... I have a view where you have several links which let you show a div with several tabs and select one of them. This works fine. But if I change the tab through a click over it and then I hide the view with the tabs when I make click on another click I show the view with the tabs, with the tab selected from the link, that's correct, but ... with the previous tab clicked.

So, how I can deselect the tab where I have been make click over it?

Edit 1:

I'm going to post several screenshots to try to explain better my problem.

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

Edit 2:

I add this plunker to show how it works my code and you can check that if you clic on a tab, if later returns clicking a button you don't select the correct tab. https://plnkr.co/edit/y22T01OwxgttDWM1mJeH

HTML:

<body ng-controller="MainCtrl as ctrl">
    <button id="bTab1" ng-click="ctrl.buttonClicked($event)">
        Tab 1
    </button>
    <button id="bTab2" ng-click="ctrl.buttonClicked($event)">
        Tab 2
    </button>
    <button id="bTab3" ng-click="ctrl.buttonClicked($event)">
        Tab 3
    </button>
    <div ng-show = "ctrl.show_tabs">
      <div class = "row" style = "text-align: right; margin-top: 10px">
        <button ng-click="ctrl.closeTab()">
            Hide Tabs
        </button>
      </div>
      <ul class="nav nav-tabs" id="myTab">
          <li ng-class = "ctrl.active_pai"><a data-target="#pai" data-toggle="tab">PAI</a></li>
          <li ng-class = "ctrl.active_pap"><a data-target="#pap" data-toggle="tab">PAP</a></li>
          <li ng-class = "ctrl.active_ip"><a data-target="#ip" data-toggle="tab">IP</a></li>
        </ul>

        <div class="tab-content">
          <div class="tab-pane" ng-class = "ctrl.active_pai" id="pai">Content PAI</div>
          <div class="tab-pane" ng-class = "ctrl.active_pap" id="pap">Content PAP</div>
          <div class="tab-pane" ng-class = "ctrl.active_ip" id="ip">Content IP</div>
        </div>      
    </div>
 </body>

Javascript:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
var self = this;

$scope.name = 'World';
self.show_tabs = false;
self.active_pai = "";
self.active_pap = "";
self.active_ip = "";

self.buttonClicked = function(event) {
  self.show_tabs = true;

  if (event.currentTarget.id == "bTab1"){
      self.active_pai = "active";
      self.active_pap = "";
      self.active_ip = "";
  }

  if (event.currentTarget.id == "bTab2"){
      self.active_pai = "";
      self.active_pap = "active";
      self.active_ip = "";
  }

  if (event.currentTarget.id == "bTab3"){
      self.active_pai = "";
      self.active_pap = "";
      self.active_ip = "active";
  }
};

self.closeTab = function(){
  self.show_tabs = false;
}

});

Edit 3:

More problems:

In my code, I've got tabs and Bootstrap calendar and with the given solution works fine without bootstrap calendar, but If add bootstrap calendar, this doesn't work correctly.

I have modified my origina plunker and I have added a bootstrap calendar and change these libraries:

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.2/ui-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.2/ui-bootstrap-tpls.min.js"></script>

By these:

<script type="text/javascript" src="bootstrap.min.js"></script>
<script type="text/javascript" src="ui-bootstrap-tpls-0.14.3.min.js"></script> 

The code of these libraries you've got on the plunker. Plus I have added the controller which manage the bootstrap calendar.

Ok, If we go to the plunker: https://plnkr.co/edit/PaSqa0jxQjz48pzcmBMa

We can see that we have a bootstrap calendar where I cannot select day greater than today + 1. That's correct! But, If I make a click on button "Tab 2", the Tab that we can see is not 2, it's 1. If I do the same with tab 3, I've got the same result. That's wrong. The correct functionality is If I make a click on button "Tab 2", we can see tab 2, for example.

Ok, If I change on the plunker these libraries ...

<script type="text/javascript" src="bootstrap.min.js"></script>
<script type="text/javascript" src="ui-bootstrap-tpls-0.14.3.min.js"></script> 

By the given in the solution:

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.2/ui-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.2/ui-bootstrap-tpls.min.js"></script>

We can see that the tabs works correctly, but bootstrap calendar lets you to select days greater than today + 1. And this is wrong!

3
  • 2
    So confusing question. Can you make a plunker? Commented Mar 31, 2016 at 10:14
  • Or add a screenshot of the tab in tab thing you mentioned. I'm sure its something simple enough, maybe a code snippet where you handle changing div content and a screenshot before and after would be a good start. Commented Mar 31, 2016 at 10:28
  • OK. First, I post some screenshots and later I'll try to make a plunker. Thanks for your answers!!! Commented Mar 31, 2016 at 10:37

1 Answer 1

6
+100

I would recommend using angular-ui-bootstrap tabs for this. It provides angular wrappers around most of the bootstrap functionality (mostly directives), so it makes these types of things much easier to write (and code is cleaner, as you'll see below). I modified your plunkr as minimally as possible, but changed it to make use of the ui-bootstrap tabs: https://plnkr.co/edit/qqvY2acsZWbkyFCCT7qr?p=info

New Controller:

app.controller('MainCtrl', function($scope) {
    var self = this;

    $scope.name = 'World';

    self.buttonClicked = function(index) {
        self.show_tabs = true;
        self.active = index;
    };

    self.closeTab = function(){
        self.show_tabs = false;
    }

});

Html changes:

<button id="bTab1" ng-click="ctrl.buttonClicked(1)">
        Tab 1
</button>
<button id="bTab2" ng-click="ctrl.buttonClicked(2)">
        Tab 2
</button>
<button id="bTab3" ng-click="ctrl.buttonClicked(3)">
        Tab 3
</button>
...
<div ng-show = "ctrl.show_tabs">
...
    <uib-tabset active="ctrl.active">
        <uib-tab index="1" heading="PAI">Content PAI</uib-tab>
        <uib-tab index="2" heading="PAP">Content PAP</uib-tab>
        <uib-tab index="3" heading="IP">Content IP</uib-tab>
    </uib-tabset>
</div>

ctrl.active, which is passed into the active attribute on <uib-tabset> just represents the index of the currently opened tab, so just changing its value will change which tab is open/visible. There are some more attributes that can be used for these directives (you can see them on the page I linked to above), but this shows the basis of how these tab directives can be used. I haven't seen the issue you were describing above after these changes.

Sign up to request clarification or add additional context in comments.

9 Comments

I'm trying to adopt this solution to my code and ... It doesn't work!!! I don't know what happend!!! self.active property doesn't work!!! Always open tab 1 :S
Fixed it!!! I don't know why, but with self.active the property active doesn't updated correctly!!! I have to change self.active for $scope.active and now it works fine!!
when you did self.active did you make sure that you were doing ctrl.active in the html (rather than just active)?
@JoséCarlos the reason why that example is broken is because in the 0.14.3 version of ui-bootstrap-tpls, the active attribute is not supported on <uib-tabset>. This is based on the docs for that specific version: angular-ui.github.io/bootstrap/versioned-docs/0.14.3/#/tabs. That version does support the active attribute on <uib-tab> though. So the calendar is not breaking anything, it's based on what version of the library you are using (I was using a more recent version in my plunkr). So you either update the library or change your code slightly to fit with this older version.
@JoséCarlos the same thing applies for the calendar, it works differently in the newer version that the old one. The newer version doesn't use max-date attribute, instead it expects all configuration to come through the datepicker-options attribute where one property is maxDate. So you were using code that is compatible with the older version in your calendar, and code that works with newer version of the tabs, so that's why when you switched back and forth between the versions, something was always broken.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.