How to activate default nested state inside nested states? - angularjs

I have nested states inside neste state here is controller definition:
(function () {
"use strict";
angular.module("gameManagement", ["ui.router", "ngAnimate", "ngResource", "toaster"])
.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/game/MultiStepForm/step1");
$urlRouterProvider.otherwise("/game/Home");
$stateProvider
.state("Home", {
url: "/game/Home",
templateUrl: "/app/game/GameView.html",
controller: "GameController",
controllerAs: "vm"
});
$stateProvider
.state("Log", {
url: "/Game/Log",
templateUrl: "/app/Log/GameLogView.html",
controller: "GameLogController",
controllerAs: "vm"
});
$stateProvider
.state("MultiStepForm.view", {
url: "/Game/MultiStepFormView",
templateUrl: "/app/MultiStepForm/MultiStepFormView.html",
controller: "MultiStepFormViewController",
controllerAs: "MultiStepViewLogic"
})
$stateProvider
.state("MultiStepForm.Edit", {
url: "/Game/MultiStepFormEdit",
templateUrl: "/app/MultiStepFormEdit/MultiStepForm.html",
controller: "MultiStepFormEditController",
controllerAs: "MultiStepEditLogic"
})
.state('MultiStepForm.Edit.step1', {
url: '/step1',
templateUrl: '/app/MultiStepForm/NestedViews/FormStep1.html'
})
.state('MultiStepForm.Edit.step2', {
url: '/step2',
templateUrl: '/app/MultiStepForm/NestedViews/FormStep2.html'
})
.state('MultiStepForm.Edit.step3', {
url: '/step3',
templateUrl: '/app/MultiStepForm/NestedViews/FormStep3.html'
});
}]);
})();
This rows define multi-step form:
.state('MultiStepForm.Edit.step1', {
url: '/step1',
templateUrl: '/app/MultiStepForm/NestedViews/FormStep1.html'
})
.state('MultiStepForm.Edit.step2', {
url: '/step2',
templateUrl: '/app/MultiStepForm/NestedViews/FormStep2.html'
})
.state('MultiStepForm.Edit.step3', {
url: '/step3',
templateUrl: '/app/MultiStepForm/NestedViews/FormStep3.html'
});
Here is view of MultiStepForm.Edit state:
<!-- form.html -->
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div id="form-multiple-step">
<div class="page-header text-center">
<!-- the links to our nested states using relative paths -->
<!-- add the active class if the state matches our ui-sref -->
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ui-sref="MultiStepForm.Edit.step1"><span>STEP1</span></a>
<a ui-sref-active="active" ui-sref="MultiStepForm.Edit.step1"><span>STEP2</span></a>
<a ui-sref-active="active" ui-sref="MultiStepForm.Edit.step1"><span>STEP3</span></a>
</div>
</div>
<form id="single-form">
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view></div>
</form>
</div>
</div>
</div>
When MultiStepForm.Edit state activated no netsed view has been displayed they have been display only when the user press button in view form and UI-SREF activate appropriate state.
My question is how can I make MultiStepForm.Edit.step1 state display associated view by default when MultiStepForm.Edit state activated?

The most simple way here would be to use the $urlRouterProvider.when()
$urlRouterProvider.when("/game/MultiStepForm", "/game/MultiStepForm/step1");
Check the doc:
when(what, handler)
Registers a handler for a given url matching. if handle is a string, it is treated as a redirect, and is interpolated according to the syntax of match (i.e. like String.replace() for RegExp, or like a UrlMatcher pattern otherwise).
If the handler is a function, it is injectable. It gets invoked if $location matches. You have the option of inject the match object as $match.
The handler can return
falsy to indicate that the rule didn't match after all, then $urlRouter will continue trying to find another one that matches.
string which is treated as a redirect and passed to $location.url()
void or any truthy value tells $urlRouter that the url was handled.

Related

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"

I am using Angular with UI-Router and can't get multiple views to work

I have the following code:
app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function ($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise('/map');
$locationProvider.html5Mode(true);
$stateProvider
.state('map', {
url: '/map',
templateUrl: 'Views/templates/layout.html'
})
.state('map.controls', {
url: '',
views: {
'ddldistricts': {
templateUrl: 'Views/templates/ddl.districts.html',
controller: 'DistrictsListController'
},
'ddldistributors': {
templateUrl: 'Views/templates/ddl.distributors.html',
controller: 'DistributorsListController'
},
'ddlmanufacturers': {
templateUrl: 'Views/templates/ddl.manufacturers.html',
controller: 'ManufacturersListController'
}
}
});
}]);
The layout.html looks like this:
<h1>Controls</h1>
<div class="row">
<div class="col-md-3">
<div ui-view="ddldistricts"></div>
</div>
<div class="col-md-3">
<div ui-view="ddldistributors"></div>
</div>
<div class="col-md-3">
<div ui-view="ddlmanufacturers"></div>
</div>
The layout template is being displayed but none of other views are... what am I doing wrong?
I know it is something simple but for some reason I can't figure it out.
There is a working plunker
In case that we wanto a child to be default (instead of its parent) we have mark parent as abstract: true
.state('map', {
url: '/map',
abstract: true,
...
})
Then will the child with empty url used as a default redirection:
.state('map.controls', {
url: '',
...
Check it here
BUT in case, we do not want to use abstract state, we'd like to a bit smarter solution - there is one I do like the most:
Redirect a state to default substate with UI-Router in AngularJS
Also, the link to doc (describing the abstract: true solution)
How to: Set up a default/index child state

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>

Use angular ui route to pass query parameters

I'm using Angular ui route and I'm trying to pass query parameters but it doesn't work. I have followed the official wiki.
In the view I have the following code very simple
<div ng-controller="MainController">
<a ng-href="#/foo/bar?param={{make}}"><li>{{make}}</li></a>
</div>
and this is the config
function config($stateProvider, $urlRouterProvider) {
$stateProvider
.state('foo', {
url: '/foo',
templateUrl: '/partials/foo.html',
controller: 'MainController'
})
.state('foo.bar', {
url: '/bar?param',
templateUrl: 'partials/foo.bar.html',
controller: 'SecondaryController'
});
}
but when I click on the link in the view the url I get it is what I get but the route doesn't receive the request.
Use ui-sref directive to generate href link
Markup
<div ng-controller="MainController">
<a ui-sref="foo.bar({param: make})"><li>{{make}}</li></a>
</div>

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