How to properly display header/footer using angularjs and ui-router? - javascript

This is my index.html:
<body>
<div ui-view></div>
</body>
This is my app.js:
angular.module('sample', [
'auth0',
'ngRoute',
'sample.home',
'sample.header',
'sample.login',
'ui.router',
'angular-storage',
'angular-jwt'
])
.config(function myAppConfig($stateProvider, $urlRouterProvider, $routeProvider, authProvider, $httpProvider, $locationProvider,
jwtInterceptorProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'login/login.html',
controller: 'LoginCtrl'
}).state('root', {
url: '/',
abstract: true,
views: {
'header': {
templateUrl: 'home/header.html',
controller: 'HeaderCtrl'
},
'footer': {
templateUrl: 'home/footer.html'
}
},
data: {
requiresLogin: true
}
}).state('root.home', {
url: '/',
views: {
'#': {
templateUrl: 'home/home.html'
}
},
data: {
requiresLogin: true
}
})
$urlRouterProvider.otherwise('/');
authProvider.init({
domain: AUTH0_DOMAIN,
clientID: AUTH0_CLIENT_ID,
loginUrl: '/login'
});
jwtInterceptorProvider.tokenGetter = function(store) {
return store.get('token');
}
$httpProvider.interceptors.push('jwtInterceptor');
})
.run(function($rootScope, auth, store, jwtHelper, $location, $state, $stateParams) {
$rootScope.$on('$locationChangeStart', function() {
if (!auth.isAuthenticated) {
var token = store.get('token');
if (token) {
if (!jwtHelper.isTokenExpired(token)) {
auth.authenticate(store.get('profile'), token);
} else {
$location.path('/login');
}
}
}
});
})
.controller('AppCtrl', function AppCtrl($scope, $location) {
$scope.$on('$routeChangeSuccess', function(e, nextRoute) {
if (nextRoute.$$route && angular.isDefined(nextRoute.$$route.pageTitle)) {
$scope.pageTitle = nextRoute.$$route.pageTitle + ' | Auth0 Sample';
}
});
})
If I do login & the root that's commented out, everything works fine. But I need to put in a header and footer (the files are correct) and when I try the root + root.home, I get a blank screen with no errors on the browser's console either.
I'm trying to go off of a few examples from online (such as this one) but none are working out so I don't know what I'm doing wrong.
Right now my header/footer.html just say header/footer.html while home has a button on it.
Added the full app.js in case that helps. Each html (footer/header/home) just has
<h1>Home</h1>
<div ui-view></div>
Edit: index.html
<body>
<div ui-view="header"></div>
<div ui-view></div>
<div ui-view="footer"></div>
</body>
app.js
.state('root.home', {
url: '/',
views: {
'#': {
templateUrl: 'views/home.html',
controller: 'HomeCtrl'
}
},
data: {
requiresLogin: true
}
})

I believe your issue here is your route is looking for a view named container not a class.
<div ui-view="container"></div>
Since it can't find a view named that it does not insert anything in the view.
Or you can just change your view route to be:
views: {
'#': {
templateUrl: 'home/home.html'
}
Which will tell it to insert that HTML in the first unnamed view it finds.
You can find a break down of how nested views work with UI-Router here
Assuming your home.html looks like this:
<div ui-view="header"></div>
<div ui-view="footer"></div>
your route should be something like
views: {
'header#home': {
templateUrl: 'home/header.html',
controller: 'HeaderCtrl'
},
'footer#home': {
templateUrl: 'home/footer.html'
}
},
data: {
requiresLogin: true
}

Related

How to make nested views on multiple views in angular ui router?

My app is very simple. i have a home page that contains header and body. in body section I want to show login page and if URL changed to 'password/forget' I show password reset form. my templates:
index.html :
<header ui-view="header">
</header>
<div class="container-fluid">
<div class="row">
<div ui-view="main">
</div>
</div>
</div>
home.html:
<div ui-view>
</div>
And ui-router config is this:
$locationProvider.html5Mode({enabled: true, requireBase: false});
$stateProvider.state('home', {
url: '/',
views: {
'header': {
templateUrl: '/header.html'
},
'main': {
templateUrl: '/home.html'
}
}
}).state('home.forgetPassword', {
url: '/password/forget',
templateUrl: '/forgetPassword.html',
});
Now when I go "/password/forget" anything happen and index.html is showing.
I want to show forgetPassword.html when route changes to "/password/forget" .
Following this code in documentation of ui-router:
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('state1', {
url: "/state1",
templateUrl: "partials/state1.html"
})
.state('state1.list', {
url: "/list",
templateUrl: "partials/state1.list.html",
controller: function($scope) {
$scope.items = ["A", "List", "Of", "Items"];
}
})
.state('state2', {
url: "/state2",
templateUrl: "partials/state2.html"
})
.state('state2.list', {
url: "/list",
templateUrl: "partials/state2.list.html",
controller: function($scope) {
$scope.things = ["A", "Set", "Of", "Things"];
}
});
});
What i suggest is to create the 'password' state first.
Try the following solution:
$stateProvider.state('home', {
url: '/',
views: {
'header': {
templateUrl: '/header.html'
},
'main': {
templateUrl: '/home.html'
}
}
}).state('password', {
url: '/password',
templateUrl: '/password.html',
}).state('password.forgetPassword', {
url: '/forget',
templateUrl: '/forgetPassword.html',
});
Create the file 'password.html' for now, later on it might be useful for '/password' view.
Problem solved. it was for / in parent state and repeat it on child states.

Implementing a navbar nested view in angular ui router

Am new to the angular js.
Am implementing a nested ui view but the problem is when checking the current state of a page it returns many objects such that i cant use $state.current to set the ng-show
I would like the navbar shown and hidden in some states.
I have tried
The main index.html page
<html>......
<body ng-app="myapp">
<nav ng-controller="headerCtrl" ng-show="shownav()" >
//here is the navbar code..The shownav is defined on the headerCtrl
</nav>
<div ui-view> </div>
//Angular js, controllers and services links
</body>
</html>
The app.js code
var app = angular.module('myApp', ['ui.router']);
app.controller('headerCtrl',function($scope, $state) {
$scope.shownavbar = function(){
var state = $state.current;
if(state ==='login' ){
return false;
}else{
return true;
}
}
app.config(function($stateProvider, $urlRouterProvider, $httpProvider){
$stateProvider
.state('login', {
url:'/login',
templateUrl: 'templates/index/login/login.html',
controller: 'loginCtrl'
})
.state('dash', {
url: '/dash',
templateUrl:'templates/layout/dashboard.html',
abstract:true
})
.state('dash.call',{
url: '/call',
templateUrl: 'templates/index/calls/calls.html',
controller: 'callCtrl'
})
.state('dash.profile', {
url: '/profile',
templateUrl: 'templates/index/account/profile/profile.html',
controller: 'profileCtrl'
})
});
I would like the navbar hidden for some states like when a user is on the login state
At the headerctrl i have also tried
$scope.shownavbar = function(){
var state = $state.current;
$log.info(state);
}
This returns in the console:
angular.js:13708 Object {name: "", url: "^", views: null, abstract: true}
angular.js:13708 Object {name: "", url: "^", views: null, abstract: true}
angular.js:13708 Object {url: "/login", templateUrl: "templates/index/login/login.html", controller: "loginCtrl", name: "login"}
angular.js:13708 Object {url: "/login", templateUrl: "templates/index/login/login.html", controller: "loginCtrl", name: "login"}
angular.js:13708 Object {url: "/login", templateUrl: "templates/index/login/login.html", controller: "loginCtrl", name: "login"}
WHAT COULD BE THE PROBLEM
I can think in two ways to solve this.
First solution
EDITED
inside your run() put a function to see when the state is changing and hide or show the navbar.
myApp.run(function ($rootScope, $state) {
$rootScope.navbar = false;
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
if (toState.name === 'login') {//toState variable see the state you're going
$rootScope.navbar = false;
} else {
$rootScope.navbar = true;
}
});
});
and change in your ng-show="navbar"
Second solution
the second solution i can think is you use multiple views.
$stateProvider
.state('login', {
url: '/',
views: {
'navbar': {
templateUrl: null,
controller: null
},
'body': {
templateUrl: "views/login.html",
controller: 'LoginController'
}
}
})
.state('home', {
url: '/home',
views: {
'navbar': {
templateUrl: "views/navbar.html",
controller: null
},
'body': {
templateUrl: "views/inicio.html",
controller: null
}
}
});
and in your html views put something similar to this:
<div ui-view="navbar"></div>
<div ui-view="body"></div>

Tab with different controllers

In my angular.js app I have a profile view with various tabs, each one a nested view with it's own controller. What I want to do is to be able to click back and forth different tabs but always remaining in the profile view.
But every time I click on one of the tabs, e.g "nested_view_1" with url "/nested_view_1" and templateUrl: "nested_view_1.html", it changes the path to "/nested_view_1" and renders a blank page (because I didn't specified a "/nested_view_1" in my $routeProvider). Only when I click back, it shows my selected tab content inside my view
May be a problem that I'm using ui.router and ng-route at the same time.
here is my app.js file:
var app = angular.module('app', ['ngRoute', 'ui.router','ui.bootstrap','ui.bootstrap.tpls'])
app.config(['$routeProvider', '$stateProvider' ,function ($routeProvider, $stateProvider) {
$routeProvider
.when('/', {
templateUrl: '/app/views/home.html',
controller: 'HomepageCtrl'
})
.when('/articles', {
templateUrl: 'app/views/articles/index.html',
controller: 'ArticlesCtrl'
})
.when('/articles/:id', {
templateUrl: 'app/views/articles/show.html',
controller: 'ShowArticleCtrl'
})
... other routes ...
$stateProvider
.state('profile', {
abstract: true,
url: '/profile',
templateUrl: "app/views/users/profile.html",
controller: 'UserShowCtrl'
})
.state('nested_view_1', {
url: '/nested_view_1',
views: {
"tabContent": {
templateUrl: 'app/views/users/sales.html',
controller: 'UserSalesAreaCtrl'
}
}
})
.state('nested_view_2', {
url: "/nested_view_2",
views: {
"tabContent": {
templateUrl: 'app/views/users/buys.html',
controller: 'UserAreaCtrl'
}
}
})
.... all the way to nested view 4, in my case
}])
my view:
<ul class="nav nav-tabs mt-50" >
<li ng-repeat="t in tabs" class="nav-item" heading="{{t.heading}}" active="t.active">
<a ui-sref="{{t.route}}" style="font-weight: 200;" class="nav-link" ng-class="{'active'}" >
{{ t.heading }}
</a>
</li>
<div ui-view="tabContent"></div>
</ul>
my UserShowCtrl
angular.module('app').controller('UserShowCtrl', ['$scope', 'user', '$routeParams', '$location', '$state',
function ($scope, user, $routeParams, $location, $state) {
$scope.tabs = [
{ heading: 'nested_view_1', route:'nested_view_1', active:true },
{ heading: 'nested_view_2', route:'nested_view_2', active:false },
{ heading: 'nested_view_3', route:'nested_view_3', active:false },
{ heading: 'nested_view_4', route:'nested_view_4', active:false }
];
}]);
Prefix your nested routes with the parent route parent.
$stateProvider
.state('profile', {
abstract: true,
url: '/profile',
templateUrl: "app/views/users/profile.html",
controller: 'UserShowCtrl'
})
.state('profile.nested_view_1', {
url: '/nested_view_1',
views: {
"tabContent": {
templateUrl: 'app/views/users/sales.html',
controller: 'UserSalesAreaCtrl'
}
}
})
.state('profile.nested_view_2', {
url: "/nested_view_2",
views: {
"tabContent": {
templateUrl: 'app/views/users/buys.html',
controller: 'UserAreaCtrl'
}
}
})

Angular UI-Router doesn't match a defined state

I'm using UI-Router module for routing. I have 2 states that router should match the urls with them :
// Dashboard
.state('dashboard', {
url: "/dashboard",
templateUrl: "dashboard/views/index.html",
controller: "DashboardController",
...
})
// Users
.state('users', {
url: "/users",
templateUrl: "users/views/index.html",
controller: "UsersController",
...
})
// Single User
.state('users.id', {
url: "/{id:^[a-z0-9_-]{3,16}$}",
templateUrl: "users/views/show.html",
controller: "UserController",
...
})
also I have set a default route :
$urlRouterProvider.otherwise("/dashboard");
I want the router to match users state when I go to http://127.0.0.1:8000/app/#/users
and to match user state when I go to http://127.0.0.1:8000/app/#/users/testuser
Problem :
the users state works good, but the user state url doesn't get matched and redirects to the default state. What's the problem?
There is a working example
Try to use this regex def:
.state('users.id', {
url: "/{id:(?:[a-z0-9_-]{3,16})}",
These links will work
<a href="#/users">
<a href="#/users/testuser">
This will go to otherwise
<a href="#/users/xx">
Some inspiration could be found here
In case, we want to go to state 'users.id' directly, we just have to use proper call. In this extended plunker, we can see that it could be done like this:
// working
<a ui-sref="users">
<a ui-sref="users.id({id:'testword'})">
// not working - id does not fit - otherwise is used
<a ui-sref="users.id({id:'not-working simply too long'})">
The same would be with $state.go('users.id', {id:'testword'})
Check it here
Here is an example of how I've done it in the past. Maybe it will help you.
app.config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider,$rootScope,$cookieStore) {
$urlRouterProvider.otherwise("/login");
$stateProvider
.state('login', {
url: '/login',
title: 'Login',
templateUrl:'views/loginView.html',
controller: 'loginCtrl',
resolve: resolver($rootScope),
})
.state('account', {
url: '/account',
title: 'My Account',
accessLevel: 2,
resolve: resolver($rootScope,$cookieStore),
views: {
'navigation': {
templateUrl: 'views/navigationView.html',
controller: 'navigationCtrl'
},
'content': {
templateUrl: 'views/contentView.html',
controller: 'navigationCtrl'
}
}
})
.state('account.dashboard', {
url:'/dashboard',
title: 'Dashboard',
views : {
'pageContent': {
templateUrl:'views/dashboardView.html',
controller: 'dashboardCtrl'
}
}
})
.state('account.foo', {
url:'/foo',
title: 'foo',
views : {
'pageContent': {
templateUrl:'views/foo.html',
controller: 'fooCtrl'
}
}
})
.state('account.maps', {
url:'/maps',
title: 'Maps and stuff',
views : {
'pageContent': {
templateUrl:'views/mapsView.html',
controller: 'mapsCtrl'
}
}
})
}])

Trying to use nested views in angularjs with ui-router get a blank page

My setup
app/learning/learning.js
angular.module('meanApp')
.config(function($stateProvider) {
$stateProvider
.state('learning',{
templateUrl: 'app/learning/learning.html',
url: '/learning',
controller: 'LearnCtrl',
views: {
'list': {
templateUrl: 'app/learning/learning.list.html',
controller: function($scope){ }
},
'magic': {
templateUrl: 'app/learning/learning.magic.html',
controller: function($scope){ }
}
}
});
});
app/learning/learning.html
<h1>Learning</h1>
<div ui-view="list"></div>
<div ui-view="magic"></div>
app/learning/learning.list.html
<p>A list</p>
app/learning/learning.magic.html
<h2>Magic</h2>
when I navigate to /learning I get a blank page, I'm not sure what I'm doing wrong so any help would be greatly appreciated.
You shouldn't load the base template inside state when there are nested ui-view,
Define the base template inside views.
Route Code
angular.module('meanApp')
.config(function($stateProvider) {
$stateProvider
.state('learning',{
url: '/learning',
views: {
'': {
templateUrl: 'app/learning/learning.html',
controller: 'LearnCtrl'
},
'list#learning': { //you missed state name here
templateUrl: 'app/learning/learning.list.html',
controller: function($scope){ }
},
'magic#learning': { //you missed state name here
templateUrl: 'app/learning/learning.magic.html',
controller: function($scope){ }
}
}
});
});
This could Help you, Thanks.
The problem was that I was trying to load the base template inside state and I missed out the state name as Pankaj said, so the solution is...
angular.module('meanApp')
.config(function($stateProvider) {
$stateProvider
.state('learning',{
url: '/learning',
views: {
'': {
templateUrl: 'app/learning/learning.html',
controller: 'LearnCtrl'
},
'list#learning': { //you missed state name here
templateUrl: 'app/learning/learning.list.html',
controller: function($scope){ }
},
'magic#learning': { //you missed state name here
templateUrl: 'app/learning/learning.magic.html',
controller: function($scope){ }
}
}
});
});

Categories

Resources