setting active menu in angular js with routing - angularjs

Newbie in angularjs. Trying to learn some new stuffs.
I have a simple page and when the user navigates to different page I need to set active class on respective li of the menuitem. Below is the way I have added routes.
angular.module('home', ["ngRoute"]).
config(function ($routeProvider, $locationProvider) {
$routeProvider.
when('/home', { templateUrl: 'partials/home.html', controller: "homeController", activetab: "home" }).
when('/about', { templateUrl: 'partials/about.html', activetab: "about" }).
when('/gallery', { templateUrl: 'partials/gallery.html', activetab: "gallery" }).
when('/contact', { templateUrl: 'partials/contact.html', activetab: "contact" }).
when('/services', { templateUrl: 'partials/services.html', activetab: "services" }).
when('/house', { templateUrl: 'partials/house.html', activetab: "house" }).
otherwise({ redirectTo: '/home', templateUrl: 'partials/home.html', activetab: "home" });
$locationProvider.html5Mode(true);
}).controller("homeController", function ($scope, $http, $route) {
$scope.$route = $route;
});
And I will have only homecontroller which is binded only when user visits home page. Other pages will have only static data.
I've added ng-app to my html as below:
<html ng-app="home">
Below is how I've tried to add active class to li.
<ul class="nav navbar-nav">
<li ng-class="{'active': $route.current.activetab == 'home'}">Home <span class="sr-only">(current)</span></li>
<li ng-class="{'active': $route.current.activetab == 'about'}">About</li>
<li ng-class="{'active': $route.current.activetab == 'services'}">Services</li>
<li ng-class="{'active': $route.current.activetab == 'house'}">The house</li>
<li ng-class="{'active': $route.current.activetab == 'gallery'}">Gallery</li>
<li ng-class="{'active': $route.current.activetab == 'contact'}">Contact</li>
</ul>
But I had no luck in completing this. Even though navigation happens the active class does not gets added. I've followed answer mentioned in this post. Please let me know how else I can achieve this or what is my mistake here?

try this jsfiddle example I made, the reason it does not work is after you switch state, you do not have access to the $route. the $route is only accessible in your homecontroller's $scope, which I assume only applying to your home page.

Related

AngularJS routing always to main

I have the next code:
var app = angular.module('ForclazApp', ['ngRoute']);
app.config(function($routeProvider){
$routeProvider
.when("/", {
templateUrl: "partials/header.html"
})
.when("/motos", {
templateUrl: "partials/motos.html"
})
.when("/repuestos", {
templateUrl: "partials/repuestos.html"
})
.when("/taller", {
templateUrl: "partials/taller.html"
})
.when("/blog", {
templateUrl: "partials/blog.html"
})
.when("/contacto", {
templateUrl: "partials/contacto.html"
})
.otherwise({
redirectTo: '/'
});
});
Doesn't matter in which link you click, it always redirects to header.html template. I'm using AngularJS 1.6.3.
The console log doesn't show me any error.
The menu's links:
<ul class="nav navbar-nav navbar-right">
<li class="nav-li">Inicio </li>
<li class="nav-li">Motos </li>
<li class="nav-li">Repuestos </li>
<li class="nav-li">Taller </li>
<li class="nav-li">Blog </li>
<li class="nav-li">Contacto </li>
</ul>
.otherwise({
redirectTo: '/'
});
Is basically saying that if none of the other options are matched go to to the route /. Which in your case is main. Your .when(.. checks aren't matching the way you want them to.
In your html. Remove the / from all of your links. So it should look like this:
<li class="nav-li">Contacto </li>
that will match it the way you want it to.
you should remove all # . And i think you should use ui-router instead ng-router . it better for you
https://github.com/angular-ui/ui-router

AngularJS $stateprovider

I am new to angularjs, I am not able to understand the concept of $stateprovider
I want to create a header that has menu and logo and the body content should change when clicked on menu items accordingly, code is given below, please check and answer my query
HTML
<div ui-view = "header"></div>
<div ui-view = "content"></div>
JS
var App=angular.module('test', ["ui.router", "App.controllers", "ui.bootstrap"]);
App.config(function ($stateProvider){
$stateProvider
.state('test', {
url: '',
views: {
'header': { templateUrl: '/templates/header.html'}
}
});
})
Thank You
Since you have taken two views, one for header and other for content,
<div ui-view = "header"></div>
<div ui-view = "content"></div>
The route also should have two different named routes.
views: {
'header': { templateUrl: '/templates/header.html'},
'content': { templateUrl: '/templates/content.html'}
}
From this,
<div ui-view = "header"></div> opens header.html and <div ui-view = "content"></div> opens content.html
Here is the code,
var App=angular.module('test', ["ui.router", "App.controllers", "ui.bootstrap"]);
App.config(function ($stateProvider){
$stateProvider
.state('test', {
url: '',
views: {
'header': { templateUrl: '/templates/header.html'},
'content': { templateUrl: '/templates/content.html'}
}
});
})
In the HTML,
<ul class="nav nav-pills main-menu right">
<li role="presentation"><a ui-sref="test" class="active">Home</a></li>
<li role="presentation">Bus Chart</li>
<li role="presentation">My Bookings</li>
<li role="presentation">Reviews</li>
<li role="presentation">Contact</li>
</ul>
The first li click goes to our test state as given in routes.
Here is the documentation for the same
In config File
// State definitions
$stateProvider
.state('test', {
abstract: true,
views: {
'main#': {
templateUrl: 'app/../../full-view.html'
},
'header#test': {
templateUrl: '/templates/header.html' // correct path to the template
// controller: 'HeaderController as vm' if needed
},
'footer#test': {
templateUrl: '/templates/footer.html' // correct path to the template
// controller: 'FooterController as vm' if needed
}
}
});
HTML
in content-only.html
<div>
<div ui-view = "content"></div>
</div>
in full-view.html
<div class="container">
<div ui-view="header"></div>
<div>
<div ui-view="content"></div>
</div>
<div ui-view="footer"></div>
</div>
in index.html
<body>
<div ui-view="main"></div>
</body>
in other modules(example)
views: {
'content#test': {
templateUrl: 'app/main/policies/policies.html'
// controller: 'PoliciesController as vm' if needed
}
}
so that whatever you append to content#test will comes under ui-view="content"
for routing avoid using href="", use ui-sref="" since you are using ui-router
example ui-sref="app.home" or ui-sref="app.about" rather than usinghref="#/home" or href="#/about"

toggling class name based on route changes using angular-route

have 3 routes containing 3 forms Im trying to set bootstrap active class on current tab based on the current route in angular.I used angular route module. How can I achieve this. I m attaching the js code please check and help please
plnkr.co/edit/iTgNTJ74iLzlNx902qfP?p=preview
I used this.tab = 1 to default the tab where the class will be "active" first. Here's are my controller additions:
angular.module('ciwiseGenledgerApp')
.controller('MainCtrl', function () {
this.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Karma'
];
this.tab = 1;
this.selectTab = function(setTab) {
this.tab = setTab;
};
this.isSelected = function(checkTab){
return this.tab === checkTab;
};
});
I used ng-controller="MainCtrl as ctrl" in my page. Here's the snippet on the page.
<div class="collapse navbar-collapse" id="js-navbar-collapse" ng-controller="MainCtrl as ctrl">
<ul class="nav navbar-nav">
<li ng-class="{ active: ctrl.isSelected(1) }">Home</li>
<li ng-class="{ active: ctrl.isSelected(2) }"><a ng-href="#/reports" ng-click="ctrl.selectTab(2)">Reports</a></li>
<li ng-class="{ active: ctrl.isSelected(3) }"><a ng-href="#/admin" ng-click="ctrl.selectTab(3)">Admin</a></li>
<li ng-class="{ active: ctrl.isSelected(4) }"><a ng-href="#/help" ng-click="ctrl.selectTab(4)">Help</a></li>
<li ng-class="{ active: ctrl.isSelected(5) }"><a ng-href="#/about" ng-click="ctrl.selectTab(5)">About</a></li>
<li ng-class="{ active: ctrl.isSelected(6) }"><a ng-href="#/contact" ng-click="ctrl.selectTab(6)">Contact</a></li>
</ul>
</div>
My active tab code is independent of the view routing. Here's my app.js. It has the routing code for my views.
angular
.module('ciwiseGenledgerApp', [
'ngAnimate',
'ngCookies',
'ngResource',
'ngRoute',
'ngSanitize',
'ngTouch'
])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl',
controllerAs: 'main'
})
.when('/about', {
templateUrl: 'views/about.html',
controller: 'AboutCtrl',
controllerAs: 'about'
})
.when('/contact', {
templateUrl: 'views/contact.html',
controller: 'ContactCtrl',
controllerAs: 'contact'
})
.otherwise({
redirectTo: '/'
});
});
$.material.init();

AngularJS : How do I nest a view within a parent state with parameters?

I'm using the Ionic Framework to create a mobile app, but I'm having a difficult time with the UI Router. I've gotten a few screens working properly, but I can't seem to get nested views working on a state with parameters. I'd like a URL that looks like /legislator/1/profile. It would have a header with the name of legislator #1 and tabs below. The profile tab would be automatically visible and clicking on other tabs (e.g. /legislator/1/votes) would change the content, but not the header
I wound up abandoning the tabs & sidemenu starter projects to customize my nested views. Here's what I have in app.js. The home and people.* states work correctly, but I can't seem to load the legislator screen with the profile view in place. I've tried changing the abstract & controller attributes, but no luck yet.
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: "/home",
templateUrl: "templates/home.html",
controller: "homeController"
})
.state('people', {
url: "/people",
abstract: true,
templateUrl: "templates/people.html"
})
.state('people.legislators', {
url: "/legislators",
templateUrl: "templates/legislators.html",
controller: "legislatorController"
})
.state('people.following', {
url: "/following",
templateUrl: "templates/following.html",
controller: "followingController"
})
.state('legislator', {
url: "/legislator/{legislatorId:int}",
templateUrl: "templates/legislator.html",
abstract: true
})
.state('legislator.profile', {
url: "/legislator/{legislatorId:int}/profile",
templateUrl: "templates/legislator.profile.html",
controller: "profileController"
})
.state('legislator.votes', {
url: "/legislator/{legislatorId:int}/votes",
templateUrl: "templates/legislator.votes.html",
controller: "votelistController"
})
$urlRouterProvider.otherwise('/home');
// if none of the above states are matched, use this as the fall-back
})
How is this scenario supposed to work in the UI Router? Once I have $stateProvider configured, how should the tabs link to the nested states?
Thanks for any help you can give me.
Maybe your solution is as simple as replacing the classic href by Ui Router's ui-sref:
replace
<ion-tab ... href="#/legislator/{ scopeLegislatorId }/profile">...</ion-tab>
by
<ion-tab ... ui-sref="legislator.profile({ legislatorId: scopeLegislatorId })">...</ion-tab>
Where scopeLegislatorId is the legislatorId, available from your scope.
If that doesn't help, please provide us with your html files (e.g. legislator.html and legislator.profile.html).
You can use following method to create separate views.
state('people.following',{
data:{
anyVar: {
label: 'cp',
text : 'anyText'
}
},
views: {
'content#people': angularAMD.route({
template: infoView,
controller: 'custInfoCtrl',
controllerUrl: 'modules/custCtrl'
}),
'mobileView#people': angularAMD.route({
template: mobileView,
controller: 'mobileCtrl',
controllerUrl: 'modules/mobileBottomViewCtrl'
})
}
})
<pre>
<div ui-view='contentArea'> </div>
<div ui-view='mobileView'> </div>
</pre>
RobYed pointed me in the right direction to figure out the right way to define my states. Here's the bones of what I wound up with.
app.js:
.state('legislator', {
url: "/legislator",
templateUrl: "templates/legislator.header.html",
abstract: true,
})
.state('legislator.profile', {
url: "/{seq_no:int}/profile",
templateUrl: "templates/legislator.profile.html",
controller: "profileController"
})
templates/legislator.header.html:
<ion-nav-view animation="slide-left-right">
<div class="bar bar-header" ng-controller="profileController">
{{legislator.name}}
</div>
<div class="tabs tabs-striped tabs-top">
<a class="tab-item" ui-sref="legislator.profile" ng-class="{selected: is('legislator.profile')}">
{{'Profile' | translate}}
</a>
<a class="tab-item" ui-sref="legislator.votes" ng-class="{selected: is('legislator.votes')}">
{{'Votes' | translate}}
</a>
<a class="tab-item" ui-sref="legislator.stats" ng-class="{selected: is('legislator.stats')}">
{{'Stats' | translate}}
</a>
</div>
<div ui-view></div>
</ion-nav-view>
templates/legislator.profile.html:
<ion-content>
<div class="bar bar-stable has-subheader" style="height:145px;">
{{legislator.whatever}}
Content Here
</div>
</ion-content>
profileController.js:
'use strict';
angular.module('myApp').controller('profileController', function($scope, $rootScope) {
$scope.legislator = $rootScope.legislators[$stateParams.seq_no-1];
});
Links from other states:
<a ui-sref="legislator.profile({seq_no:legislator.seq_num})"></a>

How can I create a link in an angular app that loads inside a tab?

I have a link in an angular app that looks like this:
<tab ng-controller="childCtrl" heading="Children">
edit
</tab>
How can I load the link inside the tab instead of refreshing the entire view?
I like other approach with one point of handling all routes. ui.router with nested views allows to do it.
Template
<div ><a ui-sref="home.tab1" >Tab1</a></div>
<div><a ui-sref="home.tab2" >Tab2</a></div>
<br>
<div ui-view="tabs"></div>
app
var app = angular.module('plunker', ['ui.router']);
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'main.html',
controller: 'MainCtrl',
virtual: true
})
.state('home.tab1', {
url: '/tab1',
views: {
tabs: {
templateUrl: '1.html'
}
}
})
.state('home.tab2', {
url: '/tab2',
views: {
tabs: {
templateUrl: '2.html'
}
}
});
$urlRouterProvider
.otherwise('/home/tab1');
})
And demo http://plnkr.co/edit/r1jPgkMnPAMlI34gZrMA?refresh&p=preview
You could define the path to the selected tab's content when the link is clicked, and use ng-include to display it.
<div ng-repeat="parent in parents">
<div ng-repeat="child in parent.children">
<a href="" ng-click="selectPath(parent, child);">
Parent {{parent.Id}}, Child {{child.Id}}
</a>
</div>
</div>
<div ng-include="selected.path"></div>
Here is a demo: http://plnkr.co/edit/7SPnluxUfcNNQDyeC6yt?p=preview

Resources