I am developing a web application using angular js & spring-mvc.
In the header of my application
header.jsp
<nav class="navbar navbar-default navbar-fixed-top" >
<div class="container">
<div class="navbar-header" >
<a class="navbar-brand"
href="<c:url value="/home"/>" >Pipeline Tracker
</a >
</div >
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li ui-sref-active="active">
<a ui-sref="empty">PIPELINE</a>
</li>
<li ui-sref-active="active">
<a ui-sref="employees">ADMIN</a>
</li>
</ul>
</div>
</div>
</nav>
app.js
app.config(function($stateProvider, $urlRouterProvider){
$stateProvider
.state('empty', {
url: '/',
view: {
'main':{
templateUrl: 'views/templates/empty.html',
controller: 'EmptyController'
}
}
})
.state('employees',{
url: '/admin/employees',
view: {
'main':{
templateUrl: 'http://localhost:8070/PipelineClient/views/templates/employee.jsp',
controller: 'TestController'
}
}
});
$urlRouterProvider.otherwise('/');
});
I am unable to set the templateUrl property, so my app navigates perfectly. I can see url changing accordingly to '#/' and '#/admin/employees' but nothing is displayed. There is no error in the console also.
I tried to set templateUrl two ways. One with html and another with jsp using context url. None of them working.
I removed routing and checked the data loads pefectly. No issue with data loading.
for loading dependencies:
var app = angular.module('pipeline', [
'ngResource',
'infinite-scroll',
'angularSpinner',
'jcs-autoValidate',
'angular-ladda',
'mgcrea.ngStrap',
'toaster',
'ngAnimate',
'ui.router'
]);
index.jsp
<div class="container main-content">
<div ui-view="main"></div>
</div>
How to set this templateUrl property? I am relatively new to angular, so do let know if you need any more info on this.
I believe it's a syntax error, should be "views" and not "view".
.state('employees',{
url: '/admin/employees',
views: { <--- change view to views
'main':{
templateUrl: 'http://localhost:8070/PipelineClient/views/templates/employee.jsp',
controller: 'TestController'
}
}
});
I'm not familiar with the "view:" syntax you're using. does it work if you do:
.state("test", {
templateUrl: "views/templates/empty.html",
controller: 'EmptyController'
}
http://localhost:8070/#/test
Related
I'm new to Angular UI Router and am trying to create an application with nested views.
I've an index.html which hosts the 'header' state and the 'content' state. Within the content state, I have two nav bars representing a Global view and a Sub view. The Global View should open by default when the user opens the application.
However, at present, whenever I run the application, both Global and Sub view controllers are getting executed together(both views are getting loaded together).
What I wish instead is that only Global controller should get executed at first and then when the user clicks on Sub view, its controller should get executed. Following this, whenever the user switches between both the views, the controllers should reload.
I have been reading through Google and here but wasn't able to find the required solution. Please let me know if this is possible using ui-router. Thanks.
index.html
<html>
<body>
<div class="fluid-container">
<div ui-view="header"></div>
<div ui-view="content"></div>
</div>
</body>
</html>
content.html
<div class="row" style="background-color: #F9F9F8">
<div class="col-md-3"></div>
<div class="col-md-6">
<ul class="nav nav-pills nav-justified">
<li class="active"><a data-toggle="pill" href="#globalView">Global</a></li>
<li><a data-toggle="pill" href="#subView">Sub View</a></li>
</ul>
</div>
<div class="col-md-3"></div>
</div>
<div class="row">
<br>
<hr></hr>
<div class="tab-content">
<div id="globalView" class="tab-pane fade in active" ui-view="globalView"></div>
<div id="subAccountView" class="tab-pane fade" ui-view="subView"></div>
</div>
</div>
app.js
$urlRouterProvider.otherwise("/firstPage");
$urlRouterProvider.when('', '/firstPage');
$stateProvider
.state('home', {
url: '',
views: {
/** Find the views named in index.html and inject the named views**/
'header': {
templateUrl: 'views/header.html',
controller: 'headerController',
controllerAs: 'headerCtrl'
},
'content': {
templateUrl: 'views/content.html',
controller: 'contentController',
controllerAs: 'contentCtrl',
}
}
})
.state('home.summary', {
url: '/firstPage',
views: {
'globalView': {
templateUrl: "views/globalViewPage.html",
controller: "globalViewController",
controllerAs: "globalViewCtrl"
},
'subView': {
templateUrl: "views/subView.html",
controller: "subViewController",
controllerAs: "subViewCtrl"
}
}
});
I found the solution to my query by going through the tutorial provided by Weedoze in the comments. Below are the updated files.
index.html remains the same as above.
content.html
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<ul class="nav nav-pills nav-justified">
<li class="active"><a ui-sref=".globalView">Global</a></li>
<li><a ui-sref=".subView">Sub View</a></li>
</ul>
</div>
<div class="col-md-3"></div>
</div>
<div class="row">
<br>
<hr></hr>
<div class="tab-content">
<div class="tab-pane fade in active" ui-view></div>
</div>
</div>
A point to add here is that I was earlier having data-toggle="pill" in my anchor tag which was causing issues in navigating between the two child views. After digging further, I found that if this toggle is removed, the navigation works smoothly.
app.js
$urlRouterProvider.otherwise("/globalView");
$urlRouterProvider.when('', '/globalView');
$stateProvider
.state('home', {
url: '',
views: {
/** Find the views named in index.html and inject the named views**/
'header': {
templateUrl: 'views/header.html',
controller: 'headerController',
controllerAs: 'headerCtrl'
},
'content': {
templateUrl: 'views/content.html',
controller: 'contentController',
controllerAs: 'contentCtrl',
}
}
})
.state('home.globalView', {
templateUrl: "views/globalViewPage.html",
controller: "globalViewController",
controllerAs: "globalViewCtrl",
url: '/globalView'
})
.state('home.subView', {
templateUrl: "views/subView.html",
controller: "subViewController",
controllerAs: "subViewCtrl",
url: '/subView'
});
This code lets me switch between the two child views and whenever I toggle between the views, the controllers get reloaded.
I trying to use mmenu menu http://mmenu.frebsite.nl/ with my angularJS base app.
ui-sref is working but ng-click is not working with mmenu link.
Can anyone help me, what wrong I am doing it.
Main HTML Page
<body ng-app="student">
</div>
<div class="header">menu</div>
<div class="content">
<div ui-view></div>
</div>
<nav id="menu">
<ul>
<li ><a ng-href="" ng-click="holidayInfo()">Holiday</a></li>
<li><a ui-sref="notices">Notices</a></li>
</ul>
</nav>
</div>
</body>
app.js
app.config(['$urlRouterProvider', '$stateProvider', '$locationProvider','RestangularProvider',
function ($urlRouterProvider, $stateProvider, $locationProvider, RestangularProvider ) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state("home", {
url: "/",
templateUrl: 'home.html',
controller:'homeCtrl as vm',
resolve: {
currentyear: function (Restangular, $stateParams) {
return Restangular.one('CurrentACYear').get();
}
}
})
.state("notices", {
url: "/notices",
templateUrl: 'notices.html',
controller:'schoolNoticesCtrl as vm',
resolve: {
notciesList: function (Restangular, $stateParams) {
return Restangular.one('notices').get();
}
}
})
My holidayInfo() method is in homeCtrl controller.
When I do <nav id="menu" ng-controller="homeCtrl"> it throw error, not able to resolve currentyear .
You had # in the href of Holiday which is executing $urlRouter.otherwise code which is fallback URL.
It should be kept as blank
ng-href=""
Other thing would be you havent't had nav bar wrap with scope of controller where you wrote holidayInfo method. There you can have new controller for your navbar component & have holidayInfo method over there.
Markup
<nav id="menu" ng-controller="navbarCtrl">
<ul>
<li><a ng-href="#" ng-click="holidayInfo()">Holiday</a></li>
<li><a ui-sref="notices">Notices</a></li>
</ul>
</nav>
Code
app.controller('navbarCtrl', function(){
$scope.holidayInfo = function () {
console.log("i am trigeered ....")
};
})
Do update question with more info if you still found an issue.
I have an AngularJS webapp. I´m changing the application so the URLs can be multilanguage (for SEO indexing purposes).
I´m setting up my app.js, like this:
$routeProvider.when('/:language', {templateUrl: 'partials/home.html', controller: 'HomeCtrl'});
$routeProvider.when('/:language/about', {templateUrl: 'partials/about.html', controller: 'AboutCtrl'});
Then, in a service I get the language parameter with $routeParams and call my translation code with angular-translate to serve the page in the corresponding language.
Everything is working so far.
But, moreover, in the menu bar, I have a select combo box to choose the language. So, when user change the language, the url language parameter should change.
How should I do this?
Here's an example. Like I said in your other question, I'd use ui-router for this.
http://plnkr.co/edit/bCNgS07BblMHz55VBRSQ?p=preview
The language dropdown will preserve the currently selected state. So if you go to home -> paragraph, then change language, you will remain on the paragraph route but the language parameter will change.
app.js:
routerApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/en');
$stateProvider
.state('lang', {
url: '/:language',
templateUrl: 'partial-lang.html',
abstract: true,
controller: function($state, $scope) {
$scope.changeLanguage = function(language) {
$state.go($state.current.name, {language: language});
}
}
})
.state('lang.home', {
url: '',
templateUrl: 'partial-home.html'
})
.state('lang.home.list', {
url: '/list',
templateUrl: 'partial-home-list.html',
controller: function($scope) {
$scope.dogs = ['Bernese', 'Husky', 'Goldendoodle'];
}
})
.state('lang.home.paragraph', {
url: '/paragraph',
template: 'I could sure use a drink right now.'
})
.state('lang.about', {
url: '/about',
templateUrl: 'partial-about.html'
});
});
partial-lang.html:
<nav class="navbar navbar-inverse" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="#">AngularUI Router</a>
</div>
<ul class="nav navbar-nav">
<li><a ui-sref=".home">Home</a></li>
<li><a ui-sref=".about">About</a></li>
<li class="dropdown">
<a href class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Language: {{$state.params.language | uppercase}} <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href ng-click="changeLanguage('en')">English</a></li>
<li><a href ng-click="changeLanguage('fr')">Français</a></li>
<li><a href ng-click="changeLanguage('ru')">Русский</a></li>
</ul>
</li>
</ul>
</nav>
<div class="container">
<div ui-view></div>
</div>
index.html
<body ng-app="routerApp">
<div ui-view></div>
<pre>
<p>state = {{$state | json}}</p>
</pre>
</body>
The rest of the files are self-explanatory
You bind your combo box to a variable, then you can use $watch to know when it changes, and finally you can user $route to update language.
$watch info
$route info
Update:
Something like this:
$scope.$watch('language', function (newValue, oldValue) {
if (newValue !== oldValue) {
$route.updateParams({language: newValue});
}
});
UPDATE VERSION 1.0.7
$scope.$watch('language', function (newValue, oldValue) {
if (newValue !== oldValue) {
var path = $location.path();
path = path.replace('/'+oldValue+'/', '/'+newValue+'/');
console.log(path);
$location.path(path);
$route.reload();
}
});
I need to have navbar with links for two sub-views: index.file and index.stats but when one of them clicked the new navbar appears inside. How to fix it?
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state('index', {
url: '',
templateUrl: "../../index.html",
controller: "Controller"
})
.state('index.file', {
templateUrl: "../js/views/file.html"
})
.state('index.stats', {
templateUrl: "../js/views/stats.html"
})
});
index.html
<div class="container">
<nav class="navbar navbar-default">
<ul class="nav navbar-nav">
<li class="active"><a ui-sref="index.file">File</a></li>
<li class="active"><a ui-sref="index.stats">Stats</a></li>
</ul>
</nav>
<div ui-view></div>
</div>
I know your problem is solved, But this may help others.
Generally the duplication in routes occurs when you try to land into the same base html where you include other html pages.
E.g : If my index.html has something like this
<div ng-include="navbar.html"></div>
<div ui-view></div>
In the navbar.html, you try to do the following
<a ui-sref="index">index</a>
$stateprovider.state='index',{
url:'/index', template: 'index.html'});
Then the index.html would be rendered with a duplicate view with a self reference of itself. To solve the problem, avoid including the same template. (Its better to always have home.html/landing.html saperated from index.html)
My template is loading but I get an error that the controller is undefined. The controller does exist in my sources exactly at the location defined. What is wrong with this code?
Error: [ng:areq] Argument '/Scripts/controllers/wizardNavigationCtrl.js' is not a function, got undefined
http://errors.angularjs.org/1.2.14/ng/areq?p0=%2FScripts%2Fcontrollers%2FwizardNavigationCtrl.js&p1=not%20aNaNunction%2C%20got%20undefined
Index.html (root page)
<div class="container">
<div ui-view></div>
</div>
wizardLayout.html
<div>
<ul class="nav nav-tabs">
<li ng-repeat="model in models" ng-class="active: model.active">
<a ui-sref=".model-{{model.name}}">model.name</a>
</li>
<li ng-class="navStep=='addnew' ? 'active' : ''">
<a ui-sref=".newmodel"><span class="glyphicon glyphicon-plus"></span></a>
</li>
<li><a ui-sref=".other">Other</a></li>
<li><a ui-sref=".customer">Customer Info</a></li>
<li><a ui-sref=".shipping">Shipping Info</a></li>
<li><a ui-sref=".review">Review</a></li>
</ul>
</div>
<div ui-view>
</div>
app.js:
'use strict';
var myApp = angular.module('myApp', ['ui.router']);
myApp.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('wizard', {
url: '/',
templateUrl: 'Scripts/templates/wizardLayout.html',
controller: 'Scripts/controllers/wizardNavigationCtrl.js'
})
.state('wizard.newmodel', {
url: '/newmodel',
templateUrl: 'Scripts/templates/wizardModel.html',
controller: 'Scripts/controllers/wizardModelCtrl.js'
})
.state('wizard.other', {
url: '/other',
templateUrl: 'Scripts/templates/wizardOther.html',
controller: 'Scripts/controllers/wizardOtherCtrl.js'
})
.state('wizard.customer', {
url: '/customer',
templateUrl: 'Scripts/templates/wizardCustomer.html',
controller: 'Scripts/controllers/wizardCustomerCtrl.js'
})
.state('wizard.shipping', {
url: '/shipping',
templateUrl: 'Scripts/templates/wizardShipping.html',
controller: 'Scripts/controllers/wizardShippingCtrl.js'
})
.state('wizard.review', {
url: '/review',
templateUrl: 'Scripts/templates/wizardReview.html',
controller: 'Scripts/controllers/wizardReviewCtrl.js'
});
}]);
wizardNavigationCtrl.js
myApp.controller('wizardNavigationCtrl', ['wizardSvc', '$scope', function (wizardSvc, $scope) {
alert('navigation controller! ' + wizardSvc.quote.title);
$scope.navStep = 'addnew';
wizardSvc.init();
}])
The controller should be in the format MyControllerName not the name and path to the javascript file. That in mind, in order to use the controller the javascript must have been loaded by the browser already. This requires the use of a traditional script tag because angular won't find or load these scripts for you.
Taking a snippet from your code it becomes:
.state('wizard', {
url: '/',
templateUrl: 'Scripts/templates/wizardLayout.html',
controller: 'wizardNavigationCtrl'
})
And somewhere in the page you need:
<script src="Scripts/controllers/wizardNavigationCtrl.js" type="text/javascript"></script>
Hope that helps!