I have top level menu, and then I have left menus, which will be refreshed based on the selected top level menu. I am able to create that link, but as soon as I select the left menu, it goes blank as can be seen when selecting HOME.
At this time only HOME is wired up Route1 & Route2 is not wired up.
Also here is the Plunker for it
http://plnkr.co/edit/Jwow4VtNsSfMMcpv6qaa?p=preview
How do I prevent resetting/reloading of left menu on selection? I also want to keep highlighted the clicked left menu.
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<title>AngularJS: UI-Router Quick Start</title>
<!-- Bootstrap CSS -->
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="container">
<div class="navbar">
<div class="navbar-inner">
<a class="brand" ui-sref="index">Quick Start</a>
<ul class="nav">
<li><a ui-sref="index">Home</a></li>
<li><a ui-sref="route1">Route 1</a></li>
<li><a ui-sref="route2">Route 2</a></li>
</ul>
</div>
</div>
<div class="row">
<div class="span6">
<div class="well" ui-view="LeftMenu"></div>
</div>
<div class="span6">
<div class="well" ui-view="Content"></div>
</div>
</div>
<!-- Angular -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
<!-- UI-Router -->
<script src="//angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
<!-- App Script -->
<script>
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider){
$stateProvider
.state('index', {
url: "",
views: {
"LeftMenu": {
template: '<ul><li><a ui-sref="LeftMenuMenu1">Index-Left Menu1</a></li><li><a ui-sref="LeftMenuMenu2">Index-Left Menu2</a></li><li><a ui-sref="LeftMenuMenu3">Index-Left Menu3</a></li></ul>'
},
"Content": {
template: "LeftMenu index selected"
}
}
})
.state('LeftMenuMenu1', {
views:{
"Content": {
template: "LeftMenu.Menu1 selected"
}
}
})
.state('LeftMenuMenu2', {
views: {
"Content": {
template: "LeftMenu.Menu2 selected"
}
}
})
.state('LeftMenuMenu3', {
url: "",
views: {
"Content": {
template: "LeftMenu.Menu3 selected"
}
}
})
.state('route1', {
url: "/route1",
views: {
"LeftMenu": {
template: '<ul><li><a ui-sref="Route1.Menu1">Route1-Left Menu1</a></li><li><a ui-sref="Route1.Menu2">Route1-Left Menu2</a></li><li><a ui-sref="Route1.Menu3">Route1-Left Menu3</a></li></ul>'
},
"viewB": {
template: "route1.viewB"
}
}
})
.state('route2', {
url: "/route2",
views: {
"LeftMenu": {
template:'<ul><li>Route2-Left Menu1</li><li>Route2-Left Menu2</li><li>Route2-Left Menu3</li></ul>'
},
"viewB": {
template: "route2.viewB"
}
}
})
});
</script>
</body>
</html>
I think what you would want to do is to work with substates, rather than only root states. In each root state you are then able to set the left menu options.
Consider the below example where index is the root state where we set the left menu and set where we want the sub states to be rendered in the view. Each substate(index.LeftMenuMenu1, index.LeftMenuMenu2, index.LeftMenuMenu3), will then be rendered where ever we placed the <div ui-view=content></div> element.
$stateProvider
//Root state
.state('index', {
url: "",
views: {
//Set left side bar
"LeftMenu": {
template: '<ul><li><a ui-sref="index.LeftMenuMenu1">Index-Left Menu1</a></li><li><a ui-sref="index.LeftMenuMenu2">Index-Left Menu2</a></li><li><a ui-sref="index.LeftMenuMenu3">Index-Left Menu3</a></li></ul>'
},
//Each substate will live here
"Content": {
template: "<div ui-view></div>"
}
}
})
//substates
.state('index.LeftMenuMenu1', {
template: "LeftMenu.Menu1 selected"
})
.state('index.LeftMenuMenu2', {
template: "LeftMenu.Menu2 selected"
})
.state('index.LeftMenuMenu3', {
template: "LeftMenu.Menu3 selected"
})
Then you reuse this pattern for the other sections on your page.
$stateProvider
...
//Root state route 1
.state('route1', {
url: "/route1",
views: {
"LeftMenu": {
template: 'Route 1 menu options..'
},
"Content": {
template: "<div ui-view></div>"
}
}
})
.state('route1.LeftMenuMenu1', {
template: "LeftMenu.Menu1 selected"
})
.state('route1.LeftMenuMenu2', {
template: "LeftMenu.Menu2 selected"
})
//Root state route 2
.state('route2', {
url: "/route2",
views: {
"LeftMenu": {
template: 'Route 2 menu options..'
},
"Content": {
template: "<div ui-view></div>"
}
}
})
.state('route2.LeftMenuMenu1', {
template: "LeftMenu.Menu1 selected"
})
.state('route2.LeftMenuMenu2', {
template: "LeftMenu.Menu2 selected"
})
Updated plunker
However, is your case with the left menu is that you will only change the links and the view will be the same, I would recommend to user another pattern. Probably having a menu service that servers the menu options. And the for each root state you can use the onEnter property to trigger the menu options to update.
Related
The short story:
When I open up the index page using gulp watch, I see nothing.
I get the error:
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.4.12/$injector/modulerr?p0=confusionApp&p1=Er…0(http%3A%2F%2Flocalhost%3A3000%2Fscripts%2Fmain-94e7868a45.js%3A1%3A18165)
When I hit the link to see what the error is, it says that:
Failed to instantiate module {0} due to:
{1}
It then goes into ngRoute issues which I'm not using at this point, as I am using angular-ui-router.
I can't go any further without solving this problem so I'm throwing it up to you guys.
The code is below, but bear in mind,I am only including the areas I have changed in the assignment as it would be too long for this post. So if there's any other code you'd like to see, please put them into the contents.
Thanks.
header.html
...
<ul class="nav navbar-nav">
<li class="active">
<a ui-sref="app">
<span class="glyphicon glyphicon-home"
aria-hidden="true"></span> Home</a></li>
<li><a ui-sref="app.aboutus">
<span class="glyphicon glyphicon-info-sign"
aria-hidden="true"></span> About</a></li>
<li><a ui-sref="app.menu">
<span class="glyphicon glyphicon-list-alt"
aria-hidden="true"></span>
Menu</a></li>
<li><a ui-sref="app.contactus">
<i class="fa fa-envelope-o"></i> Contact</a></li>
</ul>
...
footer.html
...
<ul class="list-unstyled">
<li><a ui-sref="app">Home</a></li>
<li><a ui-sref="app.aboutus">About</a></li>
<li><a ui-sref="app.menu">Menu</a></li>
<li><a ui-sref="app.contactus">Contact</a></li>
</ul>
...
app.js
'use strict';
angular.module('confusionApp',['ui.router'])
.config(function($stateProvider, $urlRouteProvider){
$stateProvider
//route for the home page
.state('app', {
url:'/',
views: {
'header': {
templateUrl: 'views/header.html',
},
'content': {
template: '<h1>To be completed</h1>',
controller: 'IndexController'
},
'footer': {
templateUrl: 'views/footer.html',
}
}
})
//route to aboutus page
.state('app.aboutus', {
url:'aboutus',
views: {
'content#': {
template: '<h1>To be completed</h1>',
controller: 'AboutController'
}
}
})
//route to contactus page
.state('app.contactus', {
url:'contactus',
views: {
'content#': {
templateUrl: 'views/contactus.html',
controller: 'ContactController'
}
}
})
//route to menu page
.state('app.menu', {
url:'menu',
views: {
'content#': {
templateUrl: 'views/menu.html',
controller: 'MenuController'
}
}
})
//route to dishdetail page
.state('app.dishdetail', {
url:'menu/:id',
views: {
'content#': {
templateUrl: 'views/dishdetail.html',
controller: 'DishDetailController'
}
}
});
$urlRouteProvider.otherwise('/');
})
;
menu.html
...
<div class="media-left media-middle">
<a ui-sref="app.dishdetail({id: dish._id})">
<img class="media-object img-thumbnail" ng-src={{dish.image}} alt={{dish.name}} />
</a>
</div>
...
index.html
<body>
<div ui-view="header"></div>
<div ui-view="content"></div>
<div ui-view="footer"></div>
<!-- build:js scripts/main.js -->
<script src="../bower_components/angular/angular.min.js"></script>
<!-- <script src="../bower_components/angular-route/angular-route.min.js"></script> -->
<script src="../bower_components/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="scripts/app.js"></script>
<script src="scripts/controllers.js"></script>
<script src="scripts/services.js"></script>
<!-- endbuild -->
</body>
When I downloaded the new app.js file, it fixed everything, but there wasn't that much different between the two files. (Much frustration.)
The templates were replaced with templateUrls which I had actually done and everything was the same, but when I just copied and pasted the code over my code, it worked.
Here is the new working code:
'use strict';
angular.module('confusionApp', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
// route for the home page
.state('app', {
url:'/',
views: {
'header': {
templateUrl : 'views/header.html',
},
'content': {
templateUrl : 'views/home.html',
controller : 'IndexController'
},
'footer': {
templateUrl : 'views/footer.html',
}
}
})
// route for the aboutus page
.state('app.aboutus', {
url:'aboutus',
views: {
'content#': {
templateUrl : 'views/aboutus.html',
controller : 'AboutController'
}
}
})
// route for the contactus page
.state('app.contactus', {
url:'contactus',
views: {
'content#': {
templateUrl : 'views/contactus.html',
controller : 'ContactController'
}
}
})
// route for the menu page
.state('app.menu', {
url: 'menu',
views: {
'content#': {
templateUrl : 'views/menu.html',
controller : 'MenuController'
}
}
})
// route for the dishdetail page
.state('app.dishdetails', {
url: 'menu/:id',
views: {
'content#': {
templateUrl : 'views/dishdetail.html',
controller : 'DishDetailController'
}
}
});
$urlRouterProvider.otherwise('/');
})
;
And if you are facing the same issue with the same course, then please copy and paste the app.js code even if you've filled everything in correctly.
Here is my current code:
let views = { '': 'app/content.html' };
.state('auto', {
url: '/automated',
redirectToChild: {
state: 'auto.index'
},
views: view
})
.state('auto.index', {
url :'',
templateUrl: '/app/automated/automated.html'
})
.state('auto.visit', {
url: '/visit',
views: {
'': {templateUrl: '/app/automated/visit.html'}
}
})
.state('auto.visit.create', {
url: '/create',
views: {
'': {templateUrl: '/app/automated/_form.html'}
}
})
Here is my html:
// index.html
<ui-view></ui-view>
// content.html
<div class="wrapper">
<div class="container">
<ui-view> </ui-view>
</div>
</div>
// visit.html
<h5>Visit Page</h5>
// form.html
<h5>Visit Form</h5>
Here is the problem: Everything works fine with this code but when I visit auto.visit.create state it show visit.html instead of '_form.html'.
How can I replace visit.html content without changing current routes?
First Tried:
I change my auto.visit.create state to auto.visit-create. This way is working perfectly but I want create is child of auto.visit
Second Tried:
I put new <ui-view></ui-view> on visit.html but when I go to create page it will show visit.html content.
I've tried to follow this http://angular-ui.github.io/ui-router/sample/#/ code. But it's not working.
How are you visiting the nested views? The notation you want works perfectly.
you should include the <ui-view></ui-view>in all parent pages.
See the plunker I created as an example; be sure to open the preview in using the separate page view so that you can see the urls that are being generated
UPDATE
I misunderstood your question, I apologize. Below is the updated code and plunker that achieves what you desire. I don't believe there is any way to accomplish this purely through angular routing so I used jquery to do it. only changes are on first layer and second layer
http://plnkr.co/edit/cxQpu6zS7fifnb0sGvGf?p=preview
Angular Code
(function() {
angular.module("myApp", ["ui.router"]);
angular.module("myApp")
.config(["$stateProvider", "$urlRouterProvider", function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state("home", {
url: "/",
templateUrl: "blank.html"
})
.state("first", {
url: "/first",
templateUrl: "firstLayerPage.html"
})
.state("first.second", {
url: "/second",
templateUrl: "secondLayerPage.html"
})
.state("first.second.third1", {
url: "/third_Page1",
templateUrl: "thirdLayerPage1.html"
})
.state("first.second.third2", {
url: "/third_Page2",
templateUrl: "thirdLayerPage2.html"
})
}]); // end of config
})(); //end of enclosure
Index
<body ng-app="myApp">
<ul>
<li><a ui-sref="home">home</a></li>
<li><a ui-sref="first">First Layer</a> </li>
</ul>
<h1>Home Page</h1>
<hr>
<ui-view></ui-view>
</body>
first layer
<p>this is the first layer of pages.</p>
<ul>
<li><a id="showSecondLayer" ui-sref="first.second">Second Layer</a> </li>
</ul>
<hr>
<ui-view></ui-view>
<script type="text/javascript">
$(document).ready(function(){
$("#showSecondLayer").click(function(){
$("#secondLayer").show();
});
});
</script>
second layer
<div id="secondLayer">
<p>This is the second layer</p>
<ul>
<li><a id="thirdP1" ui-sref="first.second.third1">Third Layer Page 1</a> </li>
<li><a id="thirdP2" ui-sref="first.second.third2">Third Layer Page 2</a></li>
</ul>
<hr>
</div>
<ui-view></ui-view>
<script type="text/javascript">
$(document).ready(function(){
$("#thirdP1").click(function(){
$("#secondLayer").hide();
});
$("#thirdP2").click(function(){
$("#secondLayer").hide();
});
});
</script>
third layer p1
<p>This is page one of the third level of children</p>
<hr>
third layer p2
<p>This is page two of the third level of children</p>
<hr>
I'm using tabset view in one of my pages.I have divided each tab into each html pages..and I'm loading them as templates using ui-sref.
<div class="white-bg animated fadeIn">
<div class="row s-t-xs">
<div class="col-xs-10">
<div class="tabs-container">
<tabset class="tabs-left">
<tab id="tab1" heading="Job Preferences" ui-sref="user.education.jobs">
<div ng-include="'views/user/jobstab.html'"></div>
</tab>
<tab id="tab2" heading="Experience / Project Summary" ui-sref="user.education.experience">
<div ng-include="'views/user/experience.html'"></div>
</tab>
<tab id="tab3" heading="Educations / Certifications / Awards" ui-sref="user.education.certificate">
<div ng-include="'views/user/certificate.html'"></div>
</tab>
</tabset>
</div>
</div>
</div>
It is working. I can load the three templates clicking on the tabs in home page.
but I have a button in each html page which on clicked should activate the state of the next tab...
<div class="form-group">
<div class="col-md-10 col-sm-offset-9">
<button class="btn btn-primary" type="submit" ui-sref="user.education.experience">Save & Next</button>
</div>
</div>
i.e if i click the above button it should activate the 'experience' tab.
I can see that the url in the address bar is changing when i click the button but not the view.
here's my stateprovider
$stateProvider
.state('index', {
abstract: true,
url: "/index",
templateUrl: "views/common/content_user_navigation.html",
})
.state('landing', {
url: "/landing",
templateUrl: "views/landing.html",
data: { pageTitle: 'Awarded Me Home', specialClass: 'landing-page' }
})
.state('login', {
url: "/login",
templateUrl: "views/user/login.html",
data: { pageTitle: 'Login' }
})
.state('user.profile', {
url: "/profile",
templateUrl: "views/user/user_profile.html",
})
.state('user.education', {
url: "/education",
templateUrl: "views/user/education1.html",
})
.state('user.education.jobs', {
url: "/jobs",
templateUrl: "views/user/jobstab.html",
data: { pageTitle: 'Job Preferences' },
})
.state('user.education.experience', {
url: "/experience",
templateUrl: "views/user/experience.html",
data: { pageTitle: 'Experience' },
})
.state('user.education.certificate', {
url: "/certificate",
templateUrl: "views/user/certificate.html",
data: { pageTitle: 'Education' },
})
Any idea about the problem?
Within the Ionic Framework, you can setup tabs. The pages within the tabs can easily transition using a slide-left-right or some other type of transition. This makes the application feel smooth and thought-out.
The issue that I have is that the pages associated with each tab, once clicked from the tab menu, do not transition at all, there is just boom: a page.
I found a pen on codepen (link to codepen demo) that can replicate this effect as I want it (to some degree), but I cannot replicate it in any scenario, much less the Ionic rc0 (1.0) version.
The codepen code uses an animation that seems to not work elsewhere:
<ion-nav-view animation="slide-left-right"></ion-nav-view>
Please assist.
I haven't tried to get that exact example working, but I achieved a similar effect in one of my apps by giving all the tabs the same view name:
app.js
$stateProvider
.state('signin', {
url: "/sign-in",
templateUrl: "sign-in.html",
controller: 'SignInCtrl'
})
.state('forgotpassword', {
url: "/forgot-password",
templateUrl: "forgot-password.html"
})
.state('tabs', {
url: "/tab",
abstract: true,
templateUrl: "tabs.html"
})
.state('tabs.home', {
url: "/home",
views: {
'tab-view': {
templateUrl: "home.html",
controller: 'HomeTabCtrl'
}
}
})
.state('tabs.facts', {
url: "/facts",
views: {
'tab-view': {
templateUrl: "facts.html"
}
}
})
.state('tabs.facts2', {
url: "/facts2",
views: {
'tab-view': {
templateUrl: "facts2.html"
}
}
})
.state('tabs.about', {
url: "/about",
views: {
'tab-view': {
templateUrl: "about.html"
}
}
})
tabs.html
<ion-tabs tabs-style="tabs-icon-top" tabs-type="tabs-positive" animation="slide-left-right">
<ion-tab title="Home" icon="ion-home" href="#/tab/home">
<ion-nav-view name="tab-view"></ion-nav-view>
</ion-tab>
<ion-tab title="About" icon="ion-ios7-information" href="#/tab/about">
<ion-nav-view name="tab-view"></ion-nav-view>
</ion-tab>
</ion-tabs>
Notice the name "tab-view" for each state and again as the name attribute on the ion-nav-view in each tab.
This helped me to find a solution https://github.com/driftyco/ionic/issues/2997 . The trick is to load all tabs in single view. You can't use ion-tabs directive to achieve that, you you will have to create your tab container using regular html:
<ion-view title="Tabs Controller">
<!-- All tabs are going to load here -->
<ion-nav-view name="menuContent"></ion-nav-view>
<!-- TABS -->
<div class="tabs-stable tabs-icon-top tabs-bottom tabs-standard">
<div class="tab-nav tabs">
<a class="tab-item" ng-click="goTabForums()" ng-class="{ active : settings.isTab1}">
<i class="icon bb-ios-forums"></i>
<span translate="TABS.FORUMS_TAB"></span>
</a>
<a class="tab-item" ng-click="goTabGroups()" ng-class="{ active : settings.isTab2 }">
<i class="icon bb-ios-forums"></i>
<span translate="TABS.GROUPS_TAB"></span>
</a>
<a class="tab-item" ng-click="goTabTopics()" ng-class="{ active : settings.isTab2 }">
<i class="icon bb-ios-topics"></i>
<span translate="TABS.TOPICS_TAB"></span>
</a>
<a class="tab-item" ng-click="goTabNotifications()" ng-class="{ active : settings.isTab2 }">
<i class="icon bb-ios-notifications"></i>
<span translate="TABS.NOTIFICATIONS_TAB"></span>
</a>
<a class="tab-item" ng-click="goTabProfile()" ng-class="{ active : settings.isTab2 }">
<i class="icon bb-ios-my-profile"></i>
<span translate="TABS.MY_PROFILE_TAB"></span>
</a>
<a class="tab-item" ng-click="goTabMore()" ng-class="{ active : settings.isTab2 }">
<i class="icon bb-ios-more"></i>
<span translate="TABS.MORE_TAB"></span>
</a>
</div>
</div>
your tabs controller should look like this:
.controller('tabsCtrl', function($scope, $ionicConfig, $state) {
$scope.goTabForums = function(){
$ionicConfig.views.transition('platform');
$state.go('tabsController.forums');
}
$scope.goTabGroups = function(){
$ionicConfig.views.transition('platform');
$state.go('tabsController.groups');
}
$scope.goTabTopics = function(){
$ionicConfig.views.transition('platform');
$state.go('tabsController.topics');
}
$scope.goTabNotifications = function(){
$ionicConfig.views.transition('platform');
$state.go('tabsController.notifications');
}
$scope.goTabProfile = function(){
$ionicConfig.views.transition('platform');
$state.go('tabsController.profile');
}
$scope.goTabMore = function(){
$ionicConfig.views.transition('platform');
$state.go('tabsController.more');
}})
And finally routs:
$stateProvider
.state('tabsController.forums', {
url: '/forums',
views: {
'menuContent': {
templateUrl: 'templates/forums.html',
controller: 'forumsCtrl'
}
}})
.state('tabsController.topics', {
url: '/topics',
views: {
'menuContent': {
templateUrl: 'templates/topics.html',
controller: 'topicsCtrl'
}
}})
I am creating an angular js Application. which has a side bar navigation sustem. when I click on the sidebar item, then it has to show contents under that item in the content section,I am using bootstrap
See the code I've written
HTML
<div class="sidebar">
<ul>
<li ng-repeat="item in supplyItem">
<a class="span" href="#{{item.header}}">{{item.header}}</a>
</li>
</ul>
</div>
<div class="content-part">
<div class="tab-content">
<div class="tab-pane" ng-repeat="item in supplyItem" id="{{item.header}}">
{{item.desc}}
</div>
</div>
JS
myApp.config(['$routeProvider',function($routeProvider){
$routeProvider.
when('/home',{
templateUrl : 'partials/home_page.aspx',
controller:'HomePageController',
}).
when('/supplies',{
templateUrl : 'partials/supplies.aspx',
controller:'MyController',
}).
otherwise({
redirectTo: '/home'
});
}]);
appController.controller('MyController', ['$scope', function ($scope) {
$scope.supplyItem = [
{
"header": "header1",
"desc": "Descipriotn 1"
},
{
"header": "header2",
"desc": "Descipriotn 2"
}
];
$('.sidebar a').click(function (e) {
e.preventDefault();
$(this).tab('show');
});
$(function () {
$('.sidebar a:last').tab('show');
});
} ]);
but when I click on sidebar nav item it goes to the home page as i mentioned in the routeProvider.otherwise()
what is the error and how do I solve this ? any one help me please
I think you should have the ids of your tap-pane divs different:
id="item.header" should be id="{{item.header}}"
Also I noticed that in you JS you have:
$scope.supplyItem = [
{
"header": "header1",
"desc": "Descipriotn 1"
},
{
"header": "header1",
"desc": "Descipriotn 2"
}
];
And I think that the "header" values should be different in order for the bootstrap plugin to discriminate between the different divs.