How to set bootstrap navbar active class with Angular JS? How to set bootstrap navbar active class with Angular JS? angularjs angularjs

How to set bootstrap navbar active class with Angular JS?


A very elegant way is to use ng-controller to run a single controller outside of the ng-view:

<div class="collapse navbar-collapse" ng-controller="HeaderController">    <ul class="nav navbar-nav">        <li ng-class="{ active: isActive('/')}"><a href="/">Home</a></li>        <li ng-class="{ active: isActive('/dogs')}"><a href="/dogs">Dogs</a></li>        <li ng-class="{ active: isActive('/cats')}"><a href="/cats">Cats</a></li>    </ul></div><div ng-view></div>

and include in controllers.js:

function HeaderController($scope, $location) {     $scope.isActive = function (viewLocation) {         return viewLocation === $location.path();    };}


I just wrote a directive to handle this, so you can simply add the attribute bs-active-link to the parent <ul> element, and any time the route changed, it will find the matching link, and add the active class to the corresponding <li>.

You can see it in action here: http://jsfiddle.net/8mcedv3b/

Example HTML:

<ul class="nav navbar-nav" bs-active-link>  <li><a href="/home">Home</a></li>  <li><a href="/contact">Contact</a></li></ul>

Javascript:

angular.module('appName').directive('bsActiveLink', ['$location', function ($location) {return {    restrict: 'A', //use as attribute     replace: false,    link: function (scope, elem) {        //after the route has changed        scope.$on("$routeChangeSuccess", function () {            var hrefs = ['/#' + $location.path(),                         '#' + $location.path(), //html5: false                         $location.path()]; //html5: true            angular.forEach(elem.find('a'), function (a) {                a = angular.element(a);                if (-1 !== hrefs.indexOf(a.attr('href'))) {                    a.parent().addClass('active');                } else {                    a.parent().removeClass('active');                   };            });             });    }}}]);


You can have a look at AngularStrap, the navbar directive seems to be what you are looking for:

https://github.com/mgcrea/angular-strap/blob/master/src/navbar/navbar.js

.directive('bsNavbar', function($location) {  'use strict';  return {    restrict: 'A',    link: function postLink(scope, element, attrs, controller) {      // Watch for the $location      scope.$watch(function() {        return $location.path();      }, function(newValue, oldValue) {        $('li[data-match-route]', element).each(function(k, li) {          var $li = angular.element(li),            // data('match-rout') does not work with dynamic attributes            pattern = $li.attr('data-match-route'),            regexp = new RegExp('^' + pattern + '$', ['i']);          if(regexp.test(newValue)) {            $li.addClass('active');          } else {            $li.removeClass('active');          }        });      });    }  };});

To use this directive:

  1. Download AngularStrap from http://mgcrea.github.io/angular-strap/

  2. Include the script on your page after bootstrap.js:
    <script src="lib/angular-strap.js"></script>

  3. Add the directives to your module:
    angular.module('myApp', ['$strap.directives'])

  4. Add the directive to your navbar:
    <div class="navbar" bs-navbar>

  5. Add regexes on each nav item:
    <li data-match-route="/about"><a href="#/about">About</a></li>