javascriptangularjstwitter-bootstraptabsng-controller

AngularJS controller for a tab


I have three tabs in my page. I'm using tabset and tab according to Angular Bootstrap Docs.

I set a controller for the <div> which has the tabsetas

<div ng-controller="Tabs" class="panel panel-default" id="tabs-panel"> 
  <tabset  class="panel-body">
    <tab heading="Tab 1"> </tab>
    <tab heading="Tab 2"> </tab>
    <tab heading="Tab 3"> </tab>
  </tabset>
</div>

The corresponding page is enter image description here

But, when I try to add another controller for my 2nd tab as

<div ng-controller="Tabs" class="panel panel-default" id="tabs-panel"> 
  <tabset  class="panel-body">
    <tab heading="Tab 1"> </tab>
    <tab heading="Tab 2" ng-controller="Tab2> </tab>
    <tab heading="Tab 3"> </tab>
  </tabset>
</div>

enter image description here

I now find that the heading is not displayed and I can no longer click the Tab2.

Why is that? How to get back the same functionality?

Is this the right way to add another controller in an existing controller?

My app.js :

var myApp = angular.module('myApp',['ui.bootstrap']);

myApp.controller('Tabs', function ($scope) {

});


myApp.controller('Tab2', function ($scope) {

});

Solution

  • I think there are at least three ways you could organize your controller code:

    1. Everything in one TabController
    2. Custom directive for each tab
    3. Add your tab logic to the tab callback function.

    Please have a look at the demo below or here at jsfiddle.

    It's the ui-bootstrap example code with the above mentioned points added.

    angular.module('demoApp', ['ui.bootstrap'])
        .controller('TabsDemoCtrl', TabsController)
        .directive('sepecialTab', SpecialTab);
    
    function TabsController($scope, $window) {
        $scope.tabs = [{
            title: 'Dynamic Title 1',
            content: 'Dynamic content 1'
        }, {
            title: 'Dynamic Title 2',
            content: 'Dynamic content 2',
            disabled: true
        }];
    
        $scope.alertMe = function () {
            setTimeout(function () {
                $window.alert('You\'ve selected the alert tab!');
            });
        };
    
        $scope.thirdTabCallback = function () {
            $scope.test = 'I\'m the third tab callback';
    
            $scope.clickme = function () {
                $window.alert('third tab only function');
            };
        };
    }
    
    function SpecialTab() {
        return {
            restrict: 'A',
            controller: function ($scope) {
                console.log('Special tab ctrl, runs on start.');
                $scope.hello = 'hello from special tab controller';
            }
        }
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.js"></script>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.1/ui-bootstrap.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.1/ui-bootstrap-tpls.js"></script>
    <div ng-app="demoApp" ng-controller="TabsDemoCtrl">
        <p>Select a tab by setting active binding to true:</p>
        <p>
            <button class="btn btn-default btn-sm" ng-click="tabs[0].active = true">Select second tab</button>
            <button class="btn btn-default btn-sm" ng-click="tabs[1].active = true">Select third tab</button>
        </p>
        <p>
            <button class="btn btn-default btn-sm" ng-click="tabs[1].disabled = ! tabs[1].disabled">Enable / Disable third tab</button>
        </p>
        <hr />
        <tabset>
            <tab heading="Static title">Static content</tab>
            <tab heading="Static title 2" sepecial-tab="">Static content2 {{hello}}</tab>
            <tab heading="Static title 3" select="thirdTabCallback()">Static content3 {{test}}
                <button ng-click="clickme()">click me</button>
            </tab>
            <tab ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active" disable="tab.disabled">{{tab.content}}</tab>
            <tab select="alertMe()">
                <tab-heading> <i class="glyphicon glyphicon-bell"></i> Alert!</tab-heading>I've got an HTML heading, and a select callback. Pretty cool!</tab>
        </tabset>
    </div>