2

I've created an AngularJS navigation menu and I'm trying to highlight the active menu item based on ng-repeat.

So far I have the menu working with ng-repeat, but I don't know what to put in the ng-click function for the active class to get applied.

Here's what I have:

Here is my view:

//View (in jade):
ul(ng-controller='MenuCtrl')
    li(ng-repeat='navLink in navLinks', ng-click='select(navLink)', ng-class='{active: navLink.linkhref == path}')
        a(href='{{navLink.linkhref}}') {{navLink.linktext}}

And here is my controller:

//Controller:
...
  controller('MenuCtrl', function ($scope,$location) {
    $scope.navLinks = [{
        linkhref: '/',
        linktext: 'View Dashboard',
    }, {
        linkhref: '/rpm',
        linktext: 'View RPMs',
    }, {
        linkhref: '/status',
        linktext: 'View Status',
    }, {
        linkhref: '/database',
        linktext: 'View Database',
    }, {
        linkhref: '/config',
        linktext: 'View Configurations',
    }];

    $scope.path = $location.path();

    $scope.select = function(navLink) {
        //idk what to put here to make the "active" class toggle between nav links
        //I could try this: 
        //remove "active" class from nav links
        //then add "active" class to this link
    };
  })
...

Here's a fiddle with my code:

http://jsfiddle.net/bATZ5/1/

So far here is the behavior:

  • when I go to http://localhost/status, the "View status" link has the "active" class on it. great!
  • when I click another link, the "View status" link stays "active", and the new link does not get the "active" class added.
  • basically nothing happens when i click, but refreshing the page works (because of the "path == path" thing)

Resources that were helpful:

2
  • 1
    The function should update $scope.path to navLink.linkhref (simply because those are what you compare when assigning the active class in your ng-class). jsfiddle.net/bATZ5/2 . However, it's worth noting that this simply makes your solution work. It still has flaw inherent in the original solution (e.g. somewhere on the li element that is not the link; the route won't change but the active highlight will). You might, instead, want to watch $routeChangeSuccess, or something along those lines. Commented May 15, 2015 at 18:16
  • @DRobinson It worked!! Thank you!! I'll keep workin at it, thank you for the tips! If you make an answer, I'll select it as the accepted answer Commented May 15, 2015 at 18:28

1 Answer 1

2

On your list elements, the ngClick directive is comparing the scope's path value with the navLink element's linkhref value. So if you want the item to gain the class, simply set the values:

$scope.select = function(navLink) {
    $scope.path = navLink.linkhref;
}

While this solves your problem, I believe there's a larger issue with this approach to a menu. Clicking the li element outside of the link will cause the item to appear active. Also, navigating with the keyboard (or in any way that doesn't trigger ngClick) will not update the menu.

Instead of binding the click, it might be worth exploring a method that watches the route:

function updateActiveLink(){
    $scope.path = $location.path();
}
$scope.$on('$routeChangeSuccess', updateActiveLink);

Or another option that I don't like as much:

$scope.$watch(function(){ 
    return $location.path();
}, updateActiveLink);
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.