Yuri
Yuri

Reputation: 447

how to change route for each tab in uib-tabset

When I choose a tab, I want the url to change. should I create a state for each tab ?

This is my code which works fine without changing the state .

My app.js

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

myApp.config([
            '$stateProvider',
            '$urlRouterProvider',
            function ($stateProvider, $urlRouterProvider) {

                $stateProvider.state('/', {
                    url: "",
                    views: {
                      "ratios": { templateUrl: "views/requetes.html" },
                      "reqBase": {templateUrl: "views/common.html" },
                      "SQLconsole": {templateUrl: "views/console.html" },
                    }

                  });
                $urlRouterProvider.otherwise('/');
            }]);



myApp.controller('TabsCtrl', function ($rootScope, $state, $scope, $window) {

     $scope.tabs = [
                    { title: "ratios", route: "ratios", active: true },
                    { title: "requetes de Base", route: "reqBase", active: false },
                    { title: "Console", route: "SQLconsole", active: false },
                ];

});

Tabset definition:

<div data-ng-controller="TabsCtrl">    

     <uib-tabset>
                <uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active" disable="tab.disabled">
                    <div ui-view="{{tab.route}}"></div>
                </uib-tab>
            </uib-tabset>

    </div>

Upvotes: 3

Views: 11761

Answers (3)

long2know
long2know

Reputation: 1360

As mentioned above, I recommend checking out a blog post I made previously regarding this topic.

https://long2know.com/2016/01/angular-tabbed-navigation/

I detail managing state, intercepting state, preventing navigation (conditionally), etc. It's driven by services and promises that make creating navigation workflow easy and robust.

If you prefer to not follow the link to my blog, here's a plunker:

https://embed.plnkr.co/w5xdJP?autoCloseSidebar&show=preview

And here's the basic config:

myApp.config(['$uibModalProvider', '$locationProvider', '$stateProvider', '$urlRouterProvider',
    function ($uibModalProvider, $locationProvider, $stateProvider, $urlRouterProvider) {
        $uibModalProvider.options = { animation: true, backdrop: 'static', keyboard: false };
        $locationProvider.html5Mode(false);

        $urlRouterProvider
            .when('/', '/state1')
            .otherwise("/state1");

        $stateProvider
            .state('tabs', {
                abstract: true,
                url: '/',
                views: {
                    'tabs': {
                        controller: 'tabsCtrl as tc',
                        templateUrl: 'tabs.html',
                    }
                }
            })
            .state('tabs.state1', {
                url: 'state1',
                templateUrl: 'state1.html',
                controller: function () { },
                reloadOnSearch: false
            })
            .state('tabs.state2', {
                url: 'state2',
                templateUrl: 'state2.html',
                controller: function () { },
                reloadOnSearch: false
            })
            .state('tabs.state3', {
                url: 'state3',
                templateUrl: 'state3.html',
                controller: function () { },
                reloadOnSearch: false
            })
            .state('tabs.state4', {
                url: 'state4',
                templateUrl: 'state4.html',
                controller: function () { },
                reloadOnSearch: false
            })
    }]);

myApp.run(['$log', 'navigationService', function ($log, navigationService) {
    // Note, we need a reference to the navigationService so $state events are tracked.
    $log.log("Start.");
}]);

However, I usually create a service that contains a list of the states that I will bind to the tabs:

var appStates = function ($state) {
    var
        states = [
            { name: 'state1', heading: "Tab 1", route: "tabs.state1", active: false, isVisible: true, href: $state.href("tabs.state1") },
            { name: 'state2', heading: "Tab 2", route: "tabs.state2", active: false, isVisible: true, href: $state.href("tabs.state2") },
            { name: 'state3', heading: "Tab 3", route: "tabs.state3", active: false, isVisible: true, href: $state.href("tabs.state3") },
            { name: 'state4', heading: "Tab 4", route: "tabs.state4", active: false, isVisible: true, href: $state.href("tabs.state4") }
        ];

    return {
        states: states
    };
};

appStates.$inject = ['$state'];
angular.module('long2know.services')
    .factory('appStates', appStates);

The HTML looks like this:

<script type="text/ng-template" id="tabs.html">
    <div class="row">
        <uib-tabset>
            <uib-tab ng-repeat="tab in tc.appStates" heading="{{tab.heading}}" active="tab.active" disable="tab.disabled"
                        select="tc.tabSelected(tab.route)">
            </uib-tab>
        </uib-tabset>
    </div>

    <div id="tabs-views" data-ui-view></div>
</script>

The tabController:

   var tabsCtrl = function ($state, $location, $filter, appStates, navigationService) {
        var
            vm = this,            
            initialize = function () {
                vm.appStates = appStates.states;
            };
        vm.tabSelected = function (route) {
            $state.go(route);
        };
        initialize();
    };

    tabsCtrl.$inject = ['$state', '$location', '$filter', 'appStates', 'navigationService'];
    angular
        .module('long2know.controllers')
        .controller('tabsCtrl', tabsCtrl);

Upvotes: 3

Abhay
Abhay

Reputation: 6770

Try this code :

var myApp=angular.module('app', ['ui.router','ngAnimate', 'ui.bootstrap']);
     myApp.config([
          '$stateProvider',
          '$urlRouterProvider',
          function ($stateProvider, $urlRouterProvider) {
               $stateProvider
                    .state('home', {
                         url:"/",
                         templateUrl: "views/requetes.html",
                    })
                    .state('home.ratios', {
                         url:"/ratios",
                         templateUrl: "views/requetes.html",
                    })
                    .state('home.reqBase', {
                         url:"/reqBase",
                         templateUrl: "views/common.html",
                    })
                    .state('home.SQLconsole', {
                         url:"/SQLconsole",
                         templateUrl: "views/console.html"
                    })
                    $urlRouterProvider.otherwise('/');
          }]);

Here is the working PLUNKR for this code !!

Upvotes: 5

Brian Baker
Brian Baker

Reputation: 996

Yes you should use nested states for your tabs. Something like below:

$stateProvider
  .state('main', {
    url: '/',
    templateUrl: 'main.html'
  })
  .state('main.ratios', {
    url: '/ratios',
    templateUrl: 'views/requetes.html'
  })

Here is a similar implementation with a navbar that you can use as an example.

Upvotes: 0

Related Questions