AngularJS UI Bootstrap Tabs that support routing
Asked Answered
W

10

39

I would like to use AngularJS UI Bootstrap Tabs in my project, but I need it to support routing.

For example:

Tab         URL
--------------------
Jobs       /jobs
Invoices   /invoices
Payments   /payments

As far as I can tell from the source code, the current tabs and pane directives doesn't support routing.

What would be the best way to add routing?

Wun answered 1/6, 2013 at 11:26 Comment(0)
I
40

To add routing you typically use an ng-view directive. I'm not sure it's easy enough to modify angular UI to support what you're looking for, but here's a plunker showing roughly what i think you're looking for (it's not necessarily the best way of doing it - hopefully someone can give you a better solution or improve on this)

Italy answered 2/6, 2013 at 8:31 Comment(3)
This is the best answer. Don't even bother with the angular-ui-bootstrap tab directives; just implement it with ngRoute. I'd actually just set up a Plunk demonstrating it, and was about to post my own answer, before I realized that it was the same as yours.Silicate
I like this waaay better than the Angular UI Bootstrap approach. Which I don't understand anyway btw. I see no real reason to rebuild Bootstrap.js into custom angular directives. Those need to be separate to utilize the best parts of both angular and bootstrap. Disclaimer: this is purely my 2ct.Gearwheel
Notice in the plunk how if you navigate between tabs and then navigate back (press back button on the keyboard), the proper view is rendered but the proper active tab is not? See this for a solution: https://mcmap.net/q/409585/-angularjs-bootstrap-remember-active-tabTandie
W
16

Use data-target="#tab1". Worked for me

Wrap answered 5/10, 2015 at 21:16 Comment(2)
Thanks, that solved angular route being invoked when clicking a tabVeolaver
This is a great answer when you have other elements on the page you don't want the routing to nav away from. +1 :)Kalamazoo
D
6

This answer really helped me http://odetocode.com/blogs/scott/archive/2014/04/14/deep-linking-a-tabbed-ui-with-angularjs.aspx (very simple but powerful solution)

Donn answered 18/2, 2015 at 15:40 Comment(1)
Still a great answer - easy to adapt to different backends.Algiers
B
5

I also have this requirement and I'm doing something similar to the answer provided by Chris, but I'm also using AngularUI router, because ngRouter does not support nested views and it is possible you'll have the tabs content view inside another view (I did) and that won't work with ng-view.

Bony answered 19/5, 2014 at 16:17 Comment(0)
G
2

you could pass your own custom key value pairs in the route definition and achieve this. here's a good example: http://www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side-Events.htm

Getty answered 3/7, 2013 at 5:39 Comment(2)
Link only answers are not allowed. Read the stackoverflow help.Vibratory
Summarize the solution so that your answer works without the link, and I'll remove the downvote.Silicate
S
2

Agree with the use of UI-Router which tracks states and works great with nested views. Speaking particularly of your Bootstrap tabs issue there is a great implementation that leverages UI Router: UI-Router Tabs

Summersummerhouse answered 9/2, 2015 at 20:59 Comment(0)
L
1

If you have a route called settings and you want to have tabs in that settings page something like this works.

<div class="right-side" align="center">
    <div class="settings-body">
        <ul class="nav nav-tabs">
          <li class="active"><a data-toggle="tab" href="#!/settings#private_email">Private email</a></li>
          <li><a data-toggle="tab" href="#!/settings#signature">Signature</a></li>
          <li><a data-toggle="tab" href="#menu2">Menu 2</a></li>
        </ul>

        <div class="tab-content">
          <div id="private_email" class="tab-pane fade in active">
            <div class="row" ng-controller="SettingsController">
                <div>
                   <button class="btn btn-primary" ng-click="activatePrivateEmail()">Activate email</button>
                   <button class="btn btn-danger">Deactivate email</button>
                </div>
            </div>
          </div>
          <div id="signature" class="tab-pane fade">
              <textarea ui-tinymce="tinymceOptions" ng-model="signature"></textarea>
              <div class="send-btn">
                <button name="send" ng-click="" class="btn btn-primary">Save signature</button>
              </div>
          </div>
          <div id="menu2" class="tab-pane fade">
            <h3>Menu 2</h3>
            <p>Some content in menu 2.</p>
          </div>
        </div>
    </div>
</div>
Leopoldine answered 19/5, 2017 at 7:1 Comment(1)
This would be my best solution, though I just remove #! in href="#!/settings#private_email" . The benefit is that you don't need to add any js code, only pure # navigation.Nullity
H
1

I got tabs with routing working the following way.

It's able to do everything you want from dynamic tabs, and it's actually very simple.

  • Tabs with a ui-view, so it can dynamically load templates,
  • Update routing in URL
  • Set history state
  • When directly navigating to a route with a tabbed view, the correct tab is marked as active.

Define the tabs with a parameter in your router

.state('app.tabs', {
    url         : '/tabs',
    template    : template/tabs.html,
})
.state('app.tabs.tab1', {
    url         : '/tab1',
    templateUrl : 'template/tab1.html',
    params      : {
        tab         : 'tab1'
    }
})
.state('app.visitors.browser.analytics', {
    url         : '/tab1',
    templateUrl : 'template/tab2.html',
    params      : {
        tab         : 'tab2'
    }
})

The tabs template (tabs.html) is

<div ng-controller="TabCtrl as $tabs">
    <uib-tabset active="$tabs.activeTab">
        <uib-tab heading="This is tab 1" index="'tab1'" ui-sref="app.tabs.tab1"></uib-tab>
        <uib-tab heading="This is tab 2" index="'tab2'" ui-sref="app.tabs.tab2"></uib-tab>
    </uib-tabset>
    <div ui-view></div>
</div>

Which is paired with a very simple controller for getting the current active tab:

app.controller('TabCtrl', function($stateParams) {
    this.activeTab = $stateParams.tab;
})
Hobby answered 30/6, 2017 at 12:56 Comment(0)
V
0

just a small add to accepted answer: i needed to keep the current tab at page refresh so i used a switch like this:

$scope.tabs = [
            { link : '#/furnizori', label : 'Furnizori' },
            { link : '#/total', label : 'Total' },
            { link : '#/clienti', label : 'Clienti' },
            { link : '#/centralizator', label : 'Centralizator' },
            { link : '#/optiuni', label : 'Optiuni' }
        ];

        switch ($location.path()) {
            case '/furnizori':
                $scope.selectedTab = $scope.tabs[0];
                break;

            case '/total':
                $scope.selectedTab = $scope.tabs[1];
                break;

            case '/clienti':
                $scope.selectedTab = $scope.tabs[2];
                break;

            case '/centralizator':
                $scope.selectedTab = $scope.tabs[3];
                break;

            case '/optiuni':
                $scope.selectedTab = $scope.tabs[4];
                break;

            default:
                $scope.selectedTab = $scope.tabs[0];
                break;
        }
Valaree answered 7/2, 2015 at 18:40 Comment(0)
P
-2

This aught to be able to do what you want:

https://github.com/angular-ui/ui-router

Preliminaries answered 7/6, 2013 at 5:2 Comment(1)
This is not enough direction to answer the question.Kalmar

© 2022 - 2024 — McMap. All rights reserved.