AngularJS - UI-Router with wizard - javascript

I'm using ui-router to setup my routes like below:
$stateProvider
.state('root', {
url: "",
templateUrl: 'path/login.html',
controller: 'LoginController'
})
.state('basket', {
url: "/basket",
views: {
'': {
templateUrl: 'path/basket.html',
controller: 'BasketController'
},
'address#basket': {
templateUrl: 'path/address.html',
controller: 'AddressController'
},
'confirmation#basket': {
templateUrl: 'path/confirmation.html',
controller: 'ConfirmationController'
},
'payment#basket': {
templateUrl: 'path/payment.html',
controller: 'PaymentController'
}
}
});
In my basket.html I'm using mgo-angular-wizard to create a "step bar".
<wizard on-finish="finishedWizard()">
<wz-step title="Address">
<div ui-view="address"></div>
</wz-step>
<wz-step title="Confirmation">
<div ui-view="confirmation"></div>
</wz-step>
<wz-step title="Payment">
<div ui-view="payment"></div>
</wz-step>
So far it's working fine. But I need to create buttons that will also navigate between those pages. For example: Address page needs a button which is going to call Confirmation page.
I saw some pages in the web which were using ui-sref="$state.go('basket.address')" but, since I'm not using this structure (with dot), I don't know how to do it (using confirmation#basket isn't working).
I'm new to Angular and learning on the flow. Thanks in advance.

In my opinion you don't need anything else except Ui.Router, because is angular you can navigate between states in a non-stateless way (saving something in services for example).
A good thing could be having nested states...
steps:
Create the parent abstract state: Basket that allows child states to inherit views, resolves, url-fragments.
Create child states: address; confirmation; payment
angular
.module('checkout', ['ui.router'])
.config(function($stateProvider) {
var basket = {
name: 'basket',
url: '/basket/',
abstract: true,
views: {
"main": {
template: "<h1>Bye</h1>",
controller: function() { alert('bye'); }
},
"sidebar": {
template: "<ul><li>LINK</li></ul>",
controller: function() { console.log('sidebar view'); }
}
}
};
var address = {
name: 'basket.address',
url: ''
};
var confirmation = {
name: 'basket.confirmation',
url: 'confirmation/',
views: {
"main#": {
template: "<h1>ss</h1>",
controller: function() { alert('ss'); }
}
}
};
var payment = {
name: 'basket.payment',
url: 'payment/',
views: {
"main#": {
template: "<h1>zz</h1>",
controller: function() { alert('zz'); }
}
}
};
$stateProvider
.state(basket)
.state(address)
.state(confirmation)
.state(payment)
;
})
;
<section ui-view="main"></section>
<aside ui-view="sidebar"></aside>
<ul>
<li><a ui-sref="basket.address">Address</a></li>
<li><a ui-sref="basket.confirmation">Confirmation</a></li>
<li><a ui-sref="basket.payment">Payment</a></li>
</ul>
Create a service via angular.module('checkout').value that stores all checkout progresses.
By the way, if you need to keep all views and states in one you probably need this Ui.Router.extra called STICKY STATES, the link provides many examples...
Hope it helps!

Related

Use same ui-view template for multiple states

I am using angularjs ui-router for a cordova app. I am trying to reuse a ui-view template (left-panel) for multiple states. This ui-view is for almost all the states except one state. I tried to refer many tutorials but still not able to implement what I want. Here is my code in app.js:
var angularApp = angular.module('angularApp', [
'ui.router',
]);
angularApp.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('root', {
abstract: true,
views: {
'left-panel': {
templateUrl: 'templates/common-left-panel.html',
},
}
})
.state('root.home', {
url: '/',
views: {
'container#': {
templateUrl: 'templates/home.html',
}
}
})
.state('root.settings', {
url: 'settings',
views: {
'container#': {
templateUrl: 'templates/settings.html',
}
}
})
.state('root.category', {
url: 'category/:catId',
views: {
'container#': {
templateUrl: 'templates/category-nodes.html',
controller: 'ListCatNodesCtrl'
}
}
})
});
This is in index.html
<div ui-view="left-panel"></div>
<a ui-sref="root.settings">Settings</a>
<div ui-view="container"></div>
With this code, the home page is rendered properly. But when I click on the settings link, there isn't any change in screen or url. In rendered DOM, I get <a ui-sref="root.settings" href="#settings">Settings</a>. The same holds for category page as well. Basically I am developing an android app using cordova and angularjs. Loads of thanks in advance.

ui router nested views condtions

is it possible to create a nested views in ui router with conditions?
The conditions is assigned to the user roles.
For example I have two types of users: admin and user.
If user is opening the setting page then ui router is adding only this view which is assign to his role.
Here is example of my config code
var app = angular.module('myApp', ['ui.router']);
app.config(function ($stateProvider, $urlRouterProvider){
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'homeController'
})
.state('settings', {
url: '/settings',
data: {
roles: ['admin', 'moderator', 'user']
},
views:{
'':{
templateUrl:'/settings.html',
},
'piView#settings':{
data: {
roles: ['user']
},
templateUrl:'/personalInformation.html'
},
'permissionsView#settings':{//load this view if user is administrator
//I need some condition for this
data: {
roles: ['admin']
},
templateUrl: '/permissionsView.html'
}
},
controller: 'settingsController'
});
$urlRouterProvider.otherwise( function($injector) {
var $state = $injector.get("$state");
$state.go('/home');
});
});
The view will be injected for each user (admin or anonymous). But we can manage which view. The best vay would be to use templateProvider.
Based on this Q & A:
Confusing $locationChangeSuccess and $stateChangeStart
I used the plunker from above source and adjusted it a bit
So, let's have these two targets (inside of index.html)
<div ui-view="onlyForAdmin"></div>
<div ui-view=""></div>
And a state public, which for Admin will reveal even content of the onlyForAdmin, with settings like this:
.state('public', {
url: "/public",
data: { isPublic: true },
views: {
'#' : {
templateUrl: 'tpl.html',
data: { isPublic: true },
},
'onlyForAdmin#' : {
templateProvider: ['$templateRequest','userService',
function($templateRequest,userService)
{
if(userService.isAdmin())
{
return $templateRequest("justForAdmin.html");
}
return ""; // other than admin will see nothing
}
]
}
}
})
the content of the justForAdmin.html (e.g. <h2>just for admin</h2>) will be injected only of some authorization service will find user as admin...
Check it here

angularjs - ui.router not rendering ui-view immediately

I am trying to use ui-router on my project.
Core module:
var core = angular.module('muhamo.core', ['angular-loading-bar', 'anguFixedHeaderTable', 'ui.router']);
Tracking module:
var app = angular.module(TRACKING_MODULE_NAME, ['muhamo.core']);
app.config(Configure);
Configure.$inject = ['$stateProvider', '$urlRouterProvider'];
function Configure($stateProvider, $urlRouterProvider) {
$stateProvider.state('contacts', {
templateUrl: '/static/partials/employee/employee-edit',
controller: function () {
this.title = 'My Contacts';
},
controllerAs: 'contact'
});
$urlRouterProvider.otherwise("/contacts");
console.log($stateProvider);
}
and the html definition :
<div ui-view></div>
It works fine if i click to a ui-sref link. But on page load it does not load the default view "/contacts". Am I missing something here?
UPDATE
It works after adding missing "url" property. But now I've another problem, if I extend my implementation like that :
function Configure($stateProvider, $urlRouterProvider) {
$stateProvider.state('employees', {
abstract: true,
url: "/employees"
/* Various other settings common to both child states */
}).state('employees.list', {
url: "", // Note the empty URL
templateUrl: '/static/partials/employee/employee-list'
});
$urlRouterProvider.otherwise("/employees");
console.log($stateProvider);
}
also with more states, ui-view is not rendering.
There are two fishy things in your implementation. You out an empty url and your default route is abstract. Try my changes below.
function Configure($stateProvider, $urlRouterProvider) {
$stateProvider.state('employees', {
abstract: true,
url: "/employees"
/* Various other settings common to both child states */
}).state('employees.list', {
url: "/list", // Note the empty URL
templateUrl: '/static/partials/employee/employee-list'
});
$urlRouterProvider.otherwise("/employees/list");
console.log($stateProvider);
Cheers
Yes. You need to set the state.url to '/contacts'
$stateProvider.state('contacts', {
url: '/contacts',
templateUrl: '/static/partials/employee/employee-edit',
controller: function () {
this.title = 'My Contacts';
},
controllerAs: 'contact'
});
It seems you forgot to set the url parameter, e.g.:
$stateProvider.state('contacts', {
url: "/contacts",
...
}

Error: Could not resolve 'storysolo' from state 'index'

I have my index.php page with a ui-sref link as follows
<a ui-sref="storysolo({ storyId: headline.nid })">
I have my main js file loading the angular code as follows
var rebelFleet = angular.module("CougsApp", ["ui.router","ngAnimate", "ui.bootstrap", "ngSanitize", "slick","CougsApp.headlines","CougsApp.story","CougsApp.recentstories" ]);
rebelFleet.config(function($stateProvider) {
// For any unmatched url, redirect to /state1
$stateProvider
.state('index', {
url: "",
views: {
"navViewPort": { templateUrl: '/components/nav/nav.html'
},
"contentViewPort": {
templateUrl: '/components/headlines/headlines.html',
controller: "headlinesCtrl"
},
"eventsViewPort": { templateUrl: '/components/scroller/scroller.html' },
"bottomContentViewPort": { templateUrl: '/components/recentstories/recentstories.html',
controller: "recentstoriesCtrl"
},
"rightsideViewPort": { templateUrl: '/components/social/social.html' },
"footerViewPort": { templateUrl: '/components/footer/footer.html' }
}
})
Then I have my story.js file trying to load with it's own routing. as follows
var ywing = angular.module('CougsApp.story', ["ui.router"]);
ywing.config(function($stateProvider, $urlRouterProvider) {
$stateProvider.state('storySolo', {
url: '/story/:storyId',
views: {
"navViewPort": { templateUrl: '/components/nav/nav.html'
},
"contentViewPort": {
templateUrl: '/components/story/story.html',
controller: "storyCtrl"
},
"footerViewPort": { templateUrl: '/components/footer/footer.html' }
}
})
});
So when I load my page and click on the ui-sref link I get this error
Could not resolve 'storysolo' from state 'index'
my order of files being loaded is as follows
angular.js,
angular-sanitize.js,
angular-ui-router.js,
rebelFleet.js, (the main js file)
story.js
I'm guessing I'm doing something wrong with the way the routes are being loaded and UI-Router hates it. Any help would be much appreciated.
There is a working example
Believe or not, it is very simple - it is about case sensitivity. State names must fit on the 1) definition as well on the 2) call side
// small solo
<a ui-sref="storysolo({ storyId: headline.nid })">
// capitalized Solo
$stateProvider.state('storySolo', {...
so just use one or the other, e.g.:
// not small solo
<a ui-sref="storySolo({ storyId: headline.nid })">
// the same name here
$stateProvider.state('storySolo', {...
Check the example here

How to update only the named view using UI-Router

I am creating a web app to help students in science, history and math. When you first land on the site I have a home/landing page. When you click get started I route to /exam/instructions. Each of my steps instructions, math and science our templates that I load into the ui-view="exam-detail". Currently the whole ui-view loads when I navigate to and from instructions through sciences. Ideally I simply want an area for pagination and an area for the subject matter and only want the ui-view="exam-detail" to update with the correct template.
I have not used UI-Router at all and any assistance would be greatly appreciated.
index.html
<div ui-view></div>
state-exam>exam.html
<div class="state-exam">
<nav ui-view="exam-pagination"></nav>
<section ui-view="exam-detail"></section>
</div>
route.js
(function() {
'use strict';
angular
.module('studentPortal')
.config(routeConfig);
function routeConfig($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'app/main/main.html',
controller: 'MainController',
controllerAs: 'main'
})
.state('exam', {
url: '/exam/:step',
abstract: true,
templateUrl: 'app/state-exam/exam.html',
controller: 'ExamController',
controllerAs: 'examController',
})
.state('exam.instructions', {
url: '/instructions',
views: {
'exam-pagination':{
templateUrl: 'app/state-exam/exam-pagination.html'
},
'exam-detail' : {
templateUrl: 'app/state-exam/exam-instructions.html'
}
}
})
.state('exam.math', {
url: '/math',
views: {
'exam-pagination':{
templateUrl: 'app/state-exam/exam-pagination.html'
},
'exam-detail' : {
templateUrl: 'app/state-exam/exam-math.html'
}
}
});
$urlRouterProvider.otherwise('/');
}
})();
There is a working plunker
There is a similar Q & A in fact, with working plunker:
Angular UI Router - Nested States with multiple layouts
Solution here, is to move the static view from child to parent. It won't be reloaded for each child (view is reloaded only if parent state is changed). We will use absolute naming (see included links for more details)
So this is the code adjustment
.state('exam', {
url: '/exam/:step',
abstract: true,
// the root view and the static pagination view
// will be defined here, so we need views : {}
views: {
'':{
templateUrl: 'app/state-exam/exam.html',
controller: 'ExamController',
controllerAs: 'examController',
},
// absolute naming targets the view defined above
'exam-pagination#exam':{
templateUrl: 'app/state-exam/exam-pagination.html'
},
}
})
.state('exam.instructions', {
url: '/instructions',
views: {
// 'exam-pagination':{}, // defined in parent
'exam-detail' : {
templateUrl: 'app/state-exam/exam-instructions.html'
}
}
})
.state('exam.math', {
url: '/math',
views: {
// 'exam-pagination':{}, // defined in parent
'exam-detail' : {
templateUrl: 'app/state-exam/exam-math.html'
}
}
});
Also check this to get more details about absolute view naming
Angular UI router nested views
Angular-UI Router: Nested Views Not Working
The working example is here

Categories