ng-class to highlight active menu item based on ng-repeat. AngularJS
Asked Answered
C

3

15

I have a menu based on the following example:

 <nav  data-ng-controller="menuContrl" class="menuItem">
     <a  data-ng-class='{active:isActive("/{{item.path}}")}' data-ng-repeat="item in menu" href="#/{{item.path}}">
         <span>{{item.title}}</span>
     </a>
 </nav>

item is an object, containing menu item information. Here is the JavaScript code for the directive and controller:

var app = angular.module("coolApp",[]);

function menuContrl($scope,$location){
    $scope.menu=menu;
    $scope.isActive = function(path){
        return ($location.path()==path)
    } 
}

The problem is that ng-class sets class to active only once during page rendering, but when you click on a menu items, nothing happenes. I suppose this is because the menu itself is not reloaded and I just change data inside <div>. So how can I make it work without reloading the whole page?

Crepitate answered 13/11, 2013 at 0:57 Comment(3)
Do you mean something like this ? http://jsfiddle.net/codef0rmer/uDPHL/Selfsatisfied
yes, that's working if you add every menu item manually. When you use ng-repeat to generate menu items, it stop working as expected.Crepitate
You could have used ui-sref-active see hereRunyon
R
0

//app.run
App.run(["$rootScope", "$state", "$stateParams",function ($rootScope, $state, $stateParams) {
        // Set reference to access them from any scope
        $rootScope.$route = $state;
}]);
        

// app.config
        $stateProvider
            .state('admin', {
                url: '/admin/',
                templateUrl: 'app/admin/admin.html',
                controller: 'AdminController',
            })
            .state('admin.dashboard', {
                url: 'dashboard',
                title: 'Dashboard',
                activetab: 'dashboard',
                controller: 'DashboardController',
                templateUrl: 'app/admin/dashboard.html',

            })
            .state('admin.view1', {
                url: 'view1',
                title: 'view1',
                activetab: 'view1',
                controller: 'view1Controller',
                templateUrl: 'app/admin/view1.html',
               
            })
            .state('admin.view2', {
                url: 'view2',
                title: 'view2',
                activetab: 'view2',
                controller: 'View2Controller',
                templateUrl: 'app/admin/view2.html',
            });
<li class="h4" ng-class="{'active': $route.current.activetab == 'dashboard'}">
                        <a>Dashboard</a>
                    </li>
                    <li class="h4" ng-class="{'active': $route.current.activetab == 'view1'}">
                        <a>view1</a>
                    </li>
                    <li class="h4" ng-class="{'active': $route.current.activetab == 'view2'}">
                        <a active-link="active">view2</a>
                    </li>
Razorback answered 12/10, 2017 at 5:54 Comment(0)
V
21

Try this out:- http://jsfiddle.net/uDPHL/146/

This issue exists in older version of angular js Reference, issue got resolved after upgrading it to angular js 1.2.0 version.

JS:-

var navList = angular.module('navList', []);    

navList.controller('navCtrl', ['$scope', '$location', function ($scope, $location) {

    $scope.navLinks = [{
        Title: 'home',
        LinkText: 'Home',
    }, {
        Title: 'about',
        LinkText: 'About Us'
    }, {
        Title: 'contact',
        LinkText: 'Contact Us'
    }];

    $scope.navClass = function (page) {
        var currentRoute = $location.path().substring(1) || 'home';
        return page === currentRoute ? 'active' : '';
    };   

}]);

HTML:-

<div class="well sidebar-nav" ng-app="navList">
    <ul class="nav nav-list" ng-controller="navCtrl">
        <li ng-repeat="navLink in navLinks" ng-class="navClass('{{navLink.Title}}')"> <a href='#/{{navLink.Title}}'>{{navLink.LinkText}}</a> 
        </li>
    </ul>
</div>
Verein answered 13/11, 2013 at 7:58 Comment(1)
@Crepitate Does this answer your question?Verein
A
16

I found it was a little easier if you go:

<li ng-repeat="i in mainMenu" ng-class="{'active':i.path == path}">

Then you can just change the $scope.path in your controller.

Aesculapius answered 9/12, 2013 at 22:40 Comment(0)
R
0

//app.run
App.run(["$rootScope", "$state", "$stateParams",function ($rootScope, $state, $stateParams) {
        // Set reference to access them from any scope
        $rootScope.$route = $state;
}]);
        

// app.config
        $stateProvider
            .state('admin', {
                url: '/admin/',
                templateUrl: 'app/admin/admin.html',
                controller: 'AdminController',
            })
            .state('admin.dashboard', {
                url: 'dashboard',
                title: 'Dashboard',
                activetab: 'dashboard',
                controller: 'DashboardController',
                templateUrl: 'app/admin/dashboard.html',

            })
            .state('admin.view1', {
                url: 'view1',
                title: 'view1',
                activetab: 'view1',
                controller: 'view1Controller',
                templateUrl: 'app/admin/view1.html',
               
            })
            .state('admin.view2', {
                url: 'view2',
                title: 'view2',
                activetab: 'view2',
                controller: 'View2Controller',
                templateUrl: 'app/admin/view2.html',
            });
<li class="h4" ng-class="{'active': $route.current.activetab == 'dashboard'}">
                        <a>Dashboard</a>
                    </li>
                    <li class="h4" ng-class="{'active': $route.current.activetab == 'view1'}">
                        <a>view1</a>
                    </li>
                    <li class="h4" ng-class="{'active': $route.current.activetab == 'view2'}">
                        <a active-link="active">view2</a>
                    </li>
Razorback answered 12/10, 2017 at 5:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.