Angular ui.router not working propely if I use target="_blank" - javascript

my route is working perfectly in my localhost.
I am using this sample but in the sample works well in my local no: http://plnkr.co/edit/AK9uYfpgTIHt9HUdHsjJ?p=preview
If I click in the link: <li class="active"><a ui-sref="details" target="_blank">Details</a></li> the page opens blank with no content
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<script src="//angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
html:
<ul class="nav nav-tabs">
<li class="active"><a ui-sref="details" target="_blank">Details</a></li>
<li><a ui-sref="users">users</a></li>
</ul>
<div class="tab-content">
<div id="details">
<div class="col-md-12">
<div ui-view></div>
</div>
</div>
</div>
angular:
var app = angular.module('app', ["ui.router"])
app.config(function($stateProvider, $urlRouterProvider){
// For any unmatched url, send to /route1
$urlRouterProvider.otherwise("/details")
$stateProvider
.state('details', {
url: "/details",
templateUrl: "app/details.html"
})
.state('users', {
url: "/users",
templateUrl: "app/users.html"
})
})

Related

Flapper News ui-view cannot display html file

I'm doing a tutorial from https://thinkster.io/tutorials/mean-stack called flapper news. I have completed the tutorial and the system work fine. But, I was thinking doing an inline template in a single file is not a good practice specially if you're doing a big project. So I tried to separate those templates into files(.html). Unfortunately the html file cannot be displayed in the ui-view. There was no error in the console nor the server. I tried to change my index.ejs file in the view folder into the public folder and rename it to index.html. Still not working.
Here is my index.html:
<html>
<head>
<title>Flapper News</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<script src="/javascripts/angularapp.js"></script>
<style>
.glyphicon-thumbs-up {
cursor: pointer
}
</style>
</head>
<body ng-app="flapperNews">
<nav class="navbar navbar-default pull-right" ng-controller="NavCtrl">
<ul class="nav navbar-nav">
<li ng-show="isLoggedIn()"><a>{{ currentUser() }}</a></li>
<li ng-show="isLoggedIn()">Log Out</li>
<li ng-hide="isLoggedIn()">Log In</li>
<li ng-hide="isLoggedIn()">Register</li>
</ul>
</nav>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
</body>
</html>
Here is one of the html file in the same public folder(home.html):
<script type="text/ng-template" id="/home.html">
<div class="page-header">
<h1>Flapper News</h1>
</div>
<div ng-repeat="post in posts | orderBy: '-upvotes'">
<span class="glyphicon glyphicon-thumbs-up" ng-click="incrementUpvotes(post)"></span> {{post.upvotes}}
<span ng-show="post.author"> posted by <a>{{post.author}}</a> |
</span>
<span style="font-size:20px; margin-left:10px;">
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</span>
<span>
Comments
</span>
</div>
<form ng-submit="addPost()" ng-show="isLoggedIn()" style="margin-top:30px;">
<div ng-hide="isLoggedIn()">
<h3>You need to Log In or Register before you can add a post.</h3>
</div>
<h3>Add a new post</h3>
<div class="form-group">
<input type="text" class="form-control" placeholder="Title" ng-model="title"></input>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Link" ng-model="link"></input>
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
public/javascripts/angularApp.js:
var app = angular.module('flapperNews', ['ui.router']);
app.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'home.html',
controller: 'MainCtrl',
resolve: {
postPromise: [
'posts',
function(posts) {
return posts.getAll();
}
]
}
})
.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'PostsCtrl',
resolve: {
post: [
'$stateParams',
'posts',
function($stateParams, posts) {
return posts.get($stateParams.id);
}
]
}
})
.state('login', {
url: '/login',
templateUrl: '/login.html',
controller: 'AuthCtrl',
onEnter: ['$state', 'auth', function($state, auth) {
if (auth.isLoggedIn()) {
$state.go('home');
}
}]
})
.state('register', {
url: '/register',
templateUrl: '/register.html',
controller: 'AuthCtrl',
onEnter: ['$state', 'auth', function($state, auth) {
if (auth.isLoggedIn()) {
$state.go('home');
}
}]
});
$urlRouterProvider.otherwise('/');
}
]);
fyi, the ".state('home', { url:" was ".state('home', { url: '/home'" but it show an error so I change it to "url: '/'" and the error was gone. But still the ui-view cannot display the templates.
This is the output:
enter image description here
Anyone has any idea on how to solve this? Does bower has anything to do with this?
You don't need the script tag once you have the template on the separate file. Remove it and it should works. You can just use the path of the file for the templateURL then
Sometimes you will something like this just like you have,
<script type="text/ng-template" id="template.html">
... some template stuff
</script>
That script tag was actually for having the template on the same file as the main template file, and you can use templateUrl with the value of the id attribute just like usual. It will treat the body of the script tag as a file of template.html since the value of the id is template.html

Using ui-routers's state params as a model

I have a simple angualr application which have dashboard that shows the different views of items. The /dasboard/:item is an abstract state. My valid urls are /dasboard/item0/view0, /dashboard/item1/view0, etc...
I want to track the current item and current view, without the additional code and only with the help of ui-router.state variable.
This part of script
<div class="">
you are looking at <strong>{{$state.current.name}}</strong> of {{$state.$current.params.item.value()}}
</div>
is printing the current item with the current view of it. This is printing the view correctly but not the item, for which I am referring the variable $state.$current.params.item.value() , the corresponding url in browser is changing the accordingly but not the text inside the div, I don't understand what I am doing wrong here.
I am expecting the value I clicked on, but instead of that, I always get the default value of parameter, which is item0.
Here is a stripped down version of my application.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<script src="https://unpkg.com/angular-ui-router/release/angular-ui-router.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myController">
<ul>
<li><a ui-sref="dashboard.view0({item: 'item0'})">item0</a></li>
<li><a ui-sref="dashboard.view0({item: 'item1'})">item1</a></li>
<li><a ui-sref="dashboard.view0({item: 'item2'})">item2</a></li>
<li><a ui-sref="dashboard.view0({item: 'item3'})">item3</a></li>
<li><a ui-sref="dashboard.view0({item: 'item4'})">item4</a></li>
</ul>
<ul>
<li><a ui-sref="dashboard.view0">view0</a></li>
<li><a ui-sref="dashboard.view1">view1</a></li>
</ul>
<div class="" ui-view>
</div>
<strong></strong>
<div class="">
you are looking at <strong>{{$state.current.name}}</strong> of {{$state.$current.params.item.value()}}
</div>
<script type="text/javascript">
angular
.module('myApp', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('dashboard',{
url: '/dashboard/:item',
params: {item: 'item0'},
controller: 'myController as vm',
abstract: true,
})
.state('dashboard.view0',{
url: '/view0',
templateUrl: 'view0.html',
controller: 'myController as vm'
})
.state('dashboard.view1',{
url: '/view1',
templateUrl: 'view0.html',
controller: 'myController as vm'
});
})
.run(function($rootScope, $state){
$rootScope.$state = $state;
})
.controller('myController', function($scope){
$scope.items = [{'image': '','name':'item0', 'alt': 'item0_logo'},
{'image': '','name':'item1','alt': 'item1_logo'},
{'image': '','name':'item2','alt': 'item2_logo'},
{'image': '','name':'item3','alt': 'item3_logo'}];
});
</script>
<script type="text/ng-template" id="view0.html">
<h2>This is view0</h2>
</script>
<script type="text/ng-template" id="view1.html">
<h2>This is view1</h2>
</script>
</body>
</html>
$stateParams service must be specified as a state controller, and it will be scoped so only the relevant parameters defined in that state are available on the service object.
Since your dashboard.view0 has no params, it is not showing any when you print them.
For more details see here

How to get state using Angular UI-Router?

I am trying to migrate my Angular routing from routeProvider to stateProvider with below code, I don't see states content when click on navbar, any idea what's wrong?
app.js
angular.module('sampleApp', ['ui.router', 'MainCtrl', 'NerdCtrl', 'NerdService'])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'views/home.html',
controller: 'MainController'
})
.state('nerd', {
url: '/nerd',
templateUrl: 'views/nerd.html',
controller: 'NerdController'
});
});
main.html
<body ng-app="sampleApp" ng-controller="NerdController">
<div class="container-fluid">
<!-- HEADER -->
<nav class="navbar navbar-inverse">
<div class="navbar-header">
<a class="navbar-brand" ui-href="home">Stencil: Node and Angular</a>
</div>
<!-- LINK TO OUR PAGES. ANGULAR HANDLES THE ROUTING HERE -->
<ul class="nav navbar-nav">
<li><a ui-sref="nerd">Nerds</a></li>
</ul>
</nav>
<!-- ANGULAR DYNAMIC CONTENT -->
<div ng-view></div>
</div>
<script src="libs/angular/angular.min.js"></script>
<script src="libs/angular-ui-router/release/angular-ui-router.min.js"></script>
<!-- ANGULAR CUSTOM -->
<script src="js/controllers/MainCtrl.js"></script>
<script src="js/controllers/NerdCtrl.js"></script>
<script src="js/services/NerdService.js"></script>
<script src="js/appRoutes.js"></script>
<script src="js/app.js"></script>
</body>
Use ui-view instead of ng-view, in that element ui-router will put template based on $location changes.
<div ui-view></div>
Remove ng-controller from body. Using, ui-router, It handles injecting the right controller for the right templates that you have defined in your $stateProvider.
Like Pankaj has pointed out, change ng-view to ui-view.
Change ui-href="home" to ui-sref="home"
I have solution for this question. some time ago i was doing the same:
in app.js:
var app=angular.module('ppl_App',['ui.router','oc.lazyLoad','ngStorage','ngFileUpload'])
Provide UI-Routing content ( In app.js ):
angular.module('ppl_App').config(function($stateProvider,$urlRouterProvider){
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('root',{
views: {
'#':{
templateUrl:'index.html'
},
'header#':{
templateUrl: 'app/views/common/header.html'
},
'content_left#':{
templateUrl: 'app/views/common/content-left.html'
},
'content_right#':{
templateUrl: 'app/views/common/contentright.html'
},
'footer#':{
templateUrl: 'app/views/common/footer.html'
}
}
})
.state('root.login',{
url:'/login',
views:{
'contentRight#root':{
templateUrl:'app/views/login.html',
controller:'loginCtrl'
},
},
})
.state('root.register',{
url:'/register',
views:{
'contentRight#root':{
templateUrl:'app/views/register.html',
controller:'registerCtrl'
},
},
})
});
See the view name in the snapshot ( In red color shape) :
Now you can use these views in your html page. ( I have used in index.html )
<body ng-app="ppl_App">
<div class="navbar navbar-inverse navbar-fixed-top" ui-view="navigation">
<div class="navbar-inner">
<div class="container">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button>
<a class="brand" href="">PPL</a>
<div class="pro_info pull-right">
<div class="pro_icn"><img src="app/assests/images/pic_small.png"></div>
<div class="pro_txt">Me<b class="caret"></b></div>
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
<li><a tabindex="-1" href="#">My Profile</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="header header_fixed" ui-view="header">
<!-- //header goes here -->
</div>
<div class="container">
<div class="content_rgt" ui-view="content_right">
<!-- //right content goes here -->
</div>
<div class="content_lft" ui-view="content_left">
<!-- //left content goes here -->
</div>
</div>
<div class="clear"></div>
</div>
<div class="footr" ui-view="footer">
<!-- //footer goes here -->
</div>
<script type="text/javascript" src="app/app.js"></script>
</body>
See how to use in html in snapshot ( In red color box ):
You can redirect on this particular views using ui-sref, like this:
<div class="addtnal_acnt">
<a ui-sref="root.register">Create My Account Now !</a>
</div>
<div class="addtnal_acnt">
<br>
<a ui-sref="root.login"> Loging Again !</a>
</div>
You can redirect from controller code ( .js file ) using $state.go() :
$state.go('root.login');
or
$state.go('root.register');

AngularJS $routeprovider Routing in Mutitab

I was using this example to build the login page
angular-authentication-example
Once login to this app the home screen should have multi-tab view as mentioned in the below example
plunker
<ul class="nav nav-tabs" ng-controller="TabsCtrl">
<li ng-class="tabClass(tab)" ng-repeat="tab in tabs" tab="tab">{{tab.label}}</li>
</ul>
The issue I am facing is the multi-tab is not embedded as Single page App. As mentioned in the demo it should embed in the same view but once I integrated, it is showing as different view. For example, when I click jobs it is taking to new html page but not included in the same view as in the plunker demo .I want to use the angularjs route provider instead of state provider and the reason is login authentication example is best and I don't want to change the entire logic.
Update
Version 1 (Without routing) Plunker Demo
It will redirect to a new view if you use #/jobs syntax. Here is a complete working solution without routes:
Your code on plunker is working because you didn't include ngRoute in your code.
View in plunker demo
app.js
$scope.tabs = [
{ id : 'jobs', label : 'Jobs', templateUrl:'jobs-partial.html' },
{ id : 'invoices', label : 'Invoices',templateUrl: 'invoices-partial.html' },
{ id : 'payments', label : 'Payments',templateUrl: 'payments-partial.html' }
];
$scope.activeTab = $scope.tabs[0];
$scope.changeActiveTab = function (tab) {
$scope.activeTab = tab;
};
$scope.isActiveTab = function (tabId) {
return tabId === $scope.activeTab;
}
Inside index.html
<body ng-controller="TabsCtrl">
<ul class="nav nav-tabs" >
<li ng-class="{active: isActiveTab(tab.id)}" ng-repeat="tab in tabs">
{{tab.label}}
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade" ng-class="{'in active': isActiveTab(tab.id)}" ng-repeat="tab in tabs"
ng-include="tab.templateUrl">
</div>
</div>
</body>
Version 2 (With routing) Plunker Demo
index.html
<!DOCTYPE html>
<html ng-app="plunkerApp">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
<script src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script src="https://code.angularjs.org/1.4.8/angular-route.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
app.js
angular
.module('untitled4App', [
'ngRoute'
])
.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider.when('/jobs', {
templateUrl: '/views/jobs-partial.html',
controller: 'JobsCtrl'
}).when('/invoices', {
templateUrl: '/views/invoices-partial.html',
controller: 'InvoicesCtrl'
}).when('/payments', {
templateUrl: '/views/payments-partial.html',
controller: 'PaymentsCtrl'
});
// make this demo work in plunker
$locationProvider.html5Mode(false);
}])
.factory('tabsService', function () {
return {
tabs: function () {
return [
{id: 'jobs', label: 'Jobs'},
{id: 'invoices', label: 'Invoices'},
{id: 'payments', label: 'Payments'}
]
},
activeTab: '',
isActiveTab: function (tabId) {
return tabId === this.activeTab;
}
}
})
.controller('JobsCtrl', ['$scope', 'tabsService', function ($scope, tabsService) {
$scope.tabs = tabsService.tabs();
$scope.tabsService = tabsService;
tabsService.activeTab = $scope.tabs[0].id;
}])
.controller('InvoicesCtrl', ['$scope', 'tabsService', function ($scope, tabsService) {
$scope.tabs = tabsService.tabs();
$scope.tabsService = tabsService;
tabsService.activeTab = $scope.tabs[1].id;
}])
.controller('PaymentsCtrl', ['$scope', 'tabsService', function ($scope, tabsService) {
$scope.tabs = tabsService.tabs();
$scope.tabsService = tabsService;
tabsService.activeTab = $scope.tabs[2].id;
}]);
jobs.partial.html
<ul class="nav nav-tabs">
<li ng-class="{active: tabsService.isActiveTab(tab.id)}" ng-repeat="tab in tabs">
{{tab.label}}
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade in active">
Jobs
</div>
</div>
invoices-partial.html
<ul class="nav nav-tabs">
<li ng-class="{active: tabsService.isActiveTab(tab.id)}" ng-repeat="tab in tabs">
{{tab.label}}
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade in active">
Invoices
</div>
</div>
payments-partial.html
<ul class="nav nav-tabs">
<li ng-class="{active: tabsService.isActiveTab(tab.id)}" ng-repeat="tab in tabs">
{{tab.label}}
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade in active">
Payments
</div>
</div>

How to attach navbar only on certain pages using ui-router?

How to display a navbar on every page except landingpage, so that not have to attach a navbar file on each of needed pages? Now I have enclosed navbar on main app layout, how it should be handled to keep it DRY?
Demo (with navbar on each page):
var App = angular.module('app', ['ui.router']);
App.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'home.html'
})
.state('about', {
url: '/about',
templateUrl: 'about.html'
}).state('landingpage', {
url: '/landingpage',
templateUrl: 'landingpage.html'
});
$urlRouterProvider.otherwise('/home');
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<div ng-app="app">
<div ng-include="'navbar.html'"></div>
<div class="container">
<div ui-view></div>
</div>
<script type="text/ng-template" id="navbar.html">
<nav class="navbar navbar-inverse" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" ui-sref="landingpage">LandingPage</a>
</div>
<ul class="nav navbar-nav">
<li><a ui-sref="home">Home</a></li>
<li><a ui-sref="about">About</a></li>
<li ng-hide="signedIn()">Log In</li>
<li ng-show="signedIn()"><a ng-click="logout()">Log Out</a></li>
</ul>
</nav>
</script>
<script type="text/ng-template" id="home.html">
<h1>The Homey Page</h1>
</script>
<script type="text/ng-template" id="about.html">
<h1>The About Page</h1>
</script>
<script type="text/ng-template" id="landingpage.html">
<h1>Landing Page</h1>
<a ui-sref="home">Home</a>
</script>
</div>
Created named views like <div ui-view name="nav"></div> and set the templateUrl by view by state. For the landingpage state, just don't provide a templateUrl for the nav view and it won't render the navbar.
Update: hide on landingpage not home state.
var App = angular.module('app', ['ui.router']);
App.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
views: {
nav: {
templateUrl: 'navbar.html'
},
content: {
templateUrl: 'home.html'
}
}
})
.state('about', {
url: '/about',
views: {
nav: {
templateUrl: 'navbar.html'
},
content: {
templateUrl: 'about.html'
}
}
}).state('landingpage', {
url: '/landingpage',
views: {
content: {
templateUrl: 'landingpage.html'
}
}
});
$urlRouterProvider.otherwise('/home');
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<div ng-app="app">
<div ui-view name="nav"></div>
<div class="container">
<div ui-view name="content"></div>
</div>
<script type="text/ng-template" id="navbar.html">
<nav class="navbar navbar-inverse" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" ui-sref="landingpage">LandingPage</a>
</div>
<ul class="nav navbar-nav">
<li><a ui-sref="home">Home</a></li>
<li><a ui-sref="about">About</a></li>
<li ng-hide="signedIn()">Log In</li>
<li ng-show="signedIn()"><a ng-click="logout()">Log Out</a></li>
</ul>
</nav>
</script>
<script type="text/ng-template" id="home.html">
<h1>The Homey Page</h1>
</script>
<script type="text/ng-template" id="about.html">
<h1>The About Page</h1>
</script>
<script type="text/ng-template" id="landingpage.html">
<h1>Landing Page</h1>
<a ui-sref="home">Home</a>
</script>
</div>

Categories

Resources