Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them, it only takes a minute:

I am learning Angularjs and Nodejs by developing a project. I have followed this tutorial and organised my folder structure and route configurations.

Problem: I have added a method called isActive to update ng-class based on tab click. But when I click the tab it is not calling the isActive method.

My guess is, I have done something wrong in appRoutes.js but not sure how to fix this. I am able to reach the MainController but not the methods in it.

I have another question, I need to make the Home tab active when I enter the application or when I clicked on home tab or when I click on application header too.

Below is the html and the js codes.

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <base href="/">
        <title>ets</title>
        <link rel="stylesheet" type="text/css" href="libs/bootstrap/dist/css/bootstrap.min.css">
        <link rel="stylesheet" type="text/css" href="css/ets.css">
    </head>

    <body ng-app="etsApp">
        <div id="mainDiv">
            <div>
                <section id="header_section" class="main-title"></section>
                <section id="nav_section"></section>
            </div>
            <section id="body_section">
                <div ng-view="ng-view"></div>
            </section>
            <section id="footer_section" class="footer-style"></section>
        </div>

        <script type="text/javascript" src="libs/jquery/dist/jquery.min.js"></script>       
        <script type="text/javascript" src="libs/angular/angular.min.js"></script>
        <script type="text/javascript" src="libs/angular-route/angular-route.min.js"></script>
        <script type="text/javascript" src="js/controllers/MainCtrl.js"></script>
        <script type="text/javascript" src="js/controllers/HomeCtrl.js"></script>
        <script type="text/javascript" src="js/appRoutes.js"></script>
        <script type="text/javascript" src="js/app.js"></script>
        <script type="text/javascript">
            $(document).ready(function(){
                $('#header_section').load('views/partials/header.html');
                $('#nav_section').load('views/partials/navigation_main.html');
                $('#footer_section').load('views/partials/footer.html');    
            });
        </script>
    </body>
</html>

navigation_main.html

<div>
  <nav class="navbar navbar-inverse">
    <ul class="nav navbar-nav">

      <li ng-class="{active : isActive('/home')}" id="nav_home">
        <a href="/home">Home</a>
      </li>

      <li ng-class="{active : isActive('/expensereporting')}" id="nav_exprep">
        <a href="/expensereporting">Expense Reporting</a>
      </li>

      <li ng-class="{active : isActive('/remainders')}">
        <a href="/remainders" id="nav_remain">Todo Remainder's</a>
      </li>

      <li ng-class="{active : isActive('/pdfoperations')}">
        <a href="/pdfoperations" id="nav_pdf">PDF Operation's</a>
      </li>

      <li ng-class="{active : isActive('/imageoperations')}">
        <a href="/imageoperations" id="nav_img">Image Operation's</a>
      </li>

    </ul>
    <ul class="nav navbar-nav navbar-right">
      <li><a href="#" style="margin-right: 20px; color: white;">Login/Register</a></li>
    </ul>
  </nav>
</div>

header.html

<div>
  <header id="header" style="margin-left: 50px;">
      <a href="/" style="text-decoration: none; color: black;">
        <strong>eTools Store</strong>
      </a> 
  </header>
</div>

appRoutes.js

angular.module('appRoutes', []).config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
    $routeProvider

        .when('/', {
            templateUrl: 'views/partials/home.html',
            controller: 'MainController'
        })

        .when('/home', {
            templateUrl: 'views/partials/home.html',
            controller: 'MainController'    
        });

        $locationProvider.html5Mode(true);
}]);

app.js

    angular.module('etsApp', ['ngRoute', 'appRoutes', 'HomeCtrl', 'MainCtrl']);

MainCtrl.js

angular.module('MainCtrl', []).controller('MainController', function($scope) {
        console.log('Main Controller');

        $scope.isActive = function(destination) {
            console.log($location.path());
            return destination === $location.path();
        }

    });
share|improve this question
    
Could just be a syntax error? - you need quotes around the class name. <li ng-class="{'active' : isActive('/pdfoperations')}"> – Tristan 2 days ago
    
@Tristan I don't think so .. pls see this answer stackoverflow.com/a/18562339/967638 – Che 2 days ago
    
can you make fiddle of this ? – Jigs 2 days ago
1  
this doesn't look right to me. aside from the bad practice of using the same controller for more than one route, you are also trying to evaluate angular expressions in an element which would not have access to the controller. The angular route provider attaches the controller to the ng-view element and the templates loaded within only, it does not make the controller available 'globally'. – Claies 2 days ago
1  
also, the practice of using JQuery .load() to inject your partials is very much not the angular way. – Claies 2 days ago

5 Answers 5

up vote 1 down vote accepted

Your navigation_main.html is outside of controller scope. That's the main reason. Try to create separate controller for you navigation like this

.controller('NavCtrl', function($scope) {
    isActive = function(destination) { /*...*/ }
}

Put it into file js/nav.js and add to your html

<script type="text/javascript" src="js/nav.js"></script>

And then add this controller to your navigation_main.html code

<div ng-controller="NavCtrl">
share|improve this answer
    
Even I have the same doubt. Good one. But I have a question how to make the nav bar to come under the MainController scope? – Che 2 days ago
    
Dont' know why you need it. Ok in this case just add MainController to navigation_main.html <div ng-controller="MainController"> – Rashad Ibrahimov 2 days ago
    
Do we need to mention the controller in the div also? Because as per the tutorial link, in appRoutes.js we write templateUrl as well as controller. The controller here means when we access a link say '/' (ROOT) then we will use the controller that is mentioned there. Am I right? I tried adding this to Navigation div but it does not work. Anyways le me write JSFiddle such that it will be easy for soem one to understand the problem – Che 2 days ago
    
You indicate controller and templateUrl in route params, i.e. you bind controller to this template. You don't need to mention controller in template view. And when routing, template view is load into <div ng-view></div>. You can use controller variables and methods only in this view, not other! For example, when / routing, home.html is load to <div ng-view></div>, and you can use MainController functions only in this view home.html, you CANNOT use MainController functions in other place of html code which is out of scope. – Rashad Ibrahimov 2 days ago
    
That's a great point. I thought the controller that is mentioend will take care of the whole page present in that link. Oh thanks for the point. – Che 2 days ago

About problem not reaching isActive method:
Try to reorganize:

    <script type="text/javascript" src="js/controllers/MainCtrl.js">         </script>
    <script type="text/javascript" src="js/controllers/HomeCtrl.js"></script>
    <script type="text/javascript" src="js/appRoutes.js"></script>
    <script type="text/javascript" src="js/app.js"></script>

into:

    <script type="text/javascript" src="js/app.js"></script>
    <script type="text/javascript" src="js/appRoutes.js"></script>
    <script type="text/javascript" src="js/controllers/MainCtrl.js"></script>
    <script type="text/javascript" src="js/controllers/HomeCtrl.js"></script>



share|improve this answer
    
Nope. Still not reaching .. :( – Che 2 days ago

May be you forget to add .otherwise

        .when('/', {
            templateUrl: 'views/partials/home.html',
            controller: 'MainController'
        })

        .when('/home', {
            templateUrl: 'views/partials/home.html',
            controller: 'MainController'    
        })
        .otherwise({
                redirectTo: '/'
            });

Update : Try this - In navigation_main.html

 <li ng-class="{'active' : path}" >
    <a href="/imageoperations" id="nav_img" ng-click="itemClicked('/imageoperations')">Image Operation's</a>
  </li>

MainCtrl.js

angular.module('MainCtrl', []).controller('MainController', function($scope) {
        console.log('Main Controller');

        $scope.itemClicked= function(destination) {
                      $scope.path = destination;
        }

    });
share|improve this answer
    
I don't think so. Otherwise acts like else part of an if-else condition just to goto the last condition if nothing else is satisfied. Anyways I have tried but nope still not reaching. – Che 2 days ago
    
Thanks man. I am able to solve it. – Che yesterday

You can try angular ui-router for your routing and for adding an active class when a state is active. You only need to add ui-sref-active="YourActiveClassHere". Angular UI-Router

Try to change the order of this,

    <script type="text/javascript" src="js/controllers/MainCtrl.js"></script>
    <script type="text/javascript" src="js/controllers/HomeCtrl.js"></script>
    <script type="text/javascript" src="js/appRoutes.js"></script>
    <script type="text/javascript" src="js/app.js"></script>

To this,

    <script type="text/javascript" src="js/app.js"></script>
    <script type="text/javascript" src="js/appRoutes.js"></script>
    <script type="text/javascript" src="js/controllers/MainCtrl.js"></script>
    <script type="text/javascript" src="js/controllers/HomeCtrl.js"></script>
share|improve this answer
    
Nope. Did not help. – Che 2 days ago

Try to add ng-click=isActive('/home'), in your a tag.

<li ng-class="{active : activeClass == 'home'}" id="nav_home">
    <a href="/home" ng-click=isActive('/home')>Home</a>
</li>

In your MainCtrl add this line,

$scope.activeClass = '';
$scope.isActive = function(destination) {
    $scope.activeClass = destination;
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.