I have three buttons, labeled About Us, Contact Us and Services. Whenever I click on a button the hash value will be changed and I have used the routing concept to go to different pages.
Now, I want to use the function $location.hash()
in AngularJS and change the color of the buttons whenever the hash value changes.
See the code that I have written below:
<div ng-controller="mainController">
<a href = "#/aboutus" ng-class="{'active': location == '/aboutus'}">About us</a>
<a href = "#/contactus" ng-class="{'active': location == '/contactus'}">Contact us</a>
<a href = "#/services" ng-class="{'active': location == '/services'}">Services</a>
</div>
Here's the angular js code that I have written :
app.controller('mainController', ['$scope', '$location', function($scope,$location){
var location = $location.hash();
}]);
Here's the css:
.active{
background-color: red;
color : white;
}
a{
padding:10px;
background-color: white;
color: black;
border: 1px solid black;
}
I don't know what's wrong with the code but I'm not able to get the color, the class is not getting added to the a tag when clicked.
As far as I can see there are two changes you need to make:
Instead of
var location = $location.hash;
You should bind you variable to the scope. Otherwise the view/template can not access it. You can do so by setting it as a property like this
$scope.location = $location.hash;
For the second part, the hash does not start with a /
but with a #
. Hence the name hash ;) . So try checking for #aboutus
instead of /aboutus
As I was building the example I figured a little flaw in the setup. This is due to Angular's way of watching variables and handling scope changes. So if you want to keep the routing and highlighting logic in the controller, I suggest you set it up like following example. This gives you complete control of how the application functions and route changes are handled.
angular.module('App', []);
angular
.module('App')
.controller('Foo', ['$scope', function($scope) {
$scope.location = 'unset';
$scope.setLocation = function(newLocation) {
console.log(newLocation);
$scope.location = newLocation;
};
}]);
a.active {
font-size: 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="App">
<div ng-controller="Foo">
<a href="#firstLocation" ng-click="setLocation('first')" ng-class="{active: location == 'first'}">First Location</a>
<a href="#somewhereElse" ng-click="setLocation('else')" ng-class="{active: location == 'else'}">Somewhere else</a>
<p>{{ location }}</p>
</div>
</div>
I would not recommend using the above code snippet. Instead hook into your routing logic. Handle the route change event to update a service which is then read from the controller to set the right classes on your links. For more information on watching route changes: How to watch for a route change in AngularJS?
The advantage of this approach is that you can be sure that the current location matches the information you've saved. If you were to provide additional options to navigate throughout the application, your location variable will be automatically updated. As opposed to the above setup which is only tracked when the actual links are clicked.
To give you a little overview:
controller
currentRoute -> returns routing service current route
service
currentRoute -> returns route as last set
setRoute -> set a new current route
routing event handler
calls 'setRoute' on the service with the new route