0

I am trying to make a directive to work with Angular UI Bootstrap Tabs.
The main purpose of this directive is to remember the tabs that have been selected.
I've looked at all the solutions out there and none seem to address this issue for tabs not set in the controller:

<tabset>
  <tab heading="Customers" sctab>Customer tab content</tab>
  <tab heading="Sales" sctab>Sales Tab Content</tab>
</tabset>

Note "sctab" is my directive name. Here I have the following working:

  • A tab is clicked it will get set the url hash as the tab heading name
  • That hash is remembered if you click a link then go back.
  • On page loading identify the tab (or element) that matches the hash

However, I have run into a road block on the final step:

  • activating the tab that matches the url hash

For this I have tried several things you can see in my code below. None have completely worked.

I believe the active state is set in an isolate-scope variable for the ui bootstrap tabs directive, called "active".

The ngClass is also bound to this variable:

ng-class="{active: active, disabled: disable}"

So basically here I've been trying to set active = true for the tab in an attempt to activate the tab (to no avail).
Before going into more detail I'll stop here to see if anyone has ideas based on what I've tried.
Here is my directive:

angular.module('jonsmodule')
.directive('sctab', ['$rootScope', '$state', '$location', function($rootScope, $state, $location) {
    return {
        restrict: "A",
        link: function (scope, element, attrs) {

            /**
             * INITIALIZING THE ACTIVE TAB FROM HASH
             */
            scope.$watch(
                // watch for setting of the element heading (so we know when the bootstrap tabs are loaded)
                function () { return element.children().first('p')[0].innerText; },
                function (newValue, oldValue) {
                    // when ui-bootstrap tabs loaded
                    if (newValue !== oldValue) {

                        // if hash matches the tab heading name
                        if ($location.hash() == newValue.trim()) {

                            /**
                             * ******** NEED HELP HERE ************
                             * THE GOAL HERE IS TO SET THE TAB ACTIVE
                             * it does not work completely
                             * below is a list of things I tried
                             */

                            //$(element).tab('show'); // .tab is not a function

                            $(element).addClass('active'); // changes the class but the tab will not change

                            scope.$$childHead.active = true; // appears to not save

                            // attrs.$set('ngClass', {active: true, disabled: false}); // this does not appear to change anything

                        } else {
                            scope.$$childHead.active = false; // appears to save and the first tab is not selected
                        }

                    }

                }
            );

            /**
             * CHANGING THE TAB
             */
            // get the state (controller)
            var current_state = $state.current.name;

            // on tab change set the hash
            element.on('click', function () {
                var tabLabel = element.children().first('p')[0].innerText;
                history.pushState(null, null, current_state + '#' + tabLabel);
            });
        },
    };
}]);
Daniel
  • 6,194
  • 7
  • 33
  • 59
Jon Robinson
  • 861
  • 2
  • 10
  • 18

1 Answers1

0

Try setting the active state of the tabs in the tab itself and pointing that at a scoped value. For example:

  <tab select="tabSelected('tab1')" active="tabs.tab1">
  <tab select="tabSelected('tab2')" active="tabs.tab2">


   $scope.tabs = {tab1: false, tab2:false};
   $scope.tabSelected = function (whichTab) {

        $scope.currentTab = whichTab;
   };

   function setTabDisplayed() {
        $scope.tabs[$scope.currentTab] = true;
    }
Scott
  • 1,690
  • 3
  • 13
  • 18
  • Thank you for your response. I could go down this route, but the point is to make the directive so I only have to do this once, and not have to update every page / controller of our platform. – Jon Robinson Jul 06 '15 at 19:17
  • I'm actually indicating that you should do that in your directive. – Scott Jul 07 '15 at 23:54