Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap 3: Deselect tab using angular js

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!

like image 607
José Carlos Avatar asked Mar 31 '16 10:03

José Carlos


1 Answers

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.

like image 109
CShark Avatar answered Sep 22 '22 10:09

CShark