ui-router wizard Id in URL - angularjs

I have a wizard based process for creating quotes. I'm using angularjs ui-router to manage the wizard urls. The routes shown below work fantastic for creating a new quote. I now need to go back in to edit existing quotes and need to figure out how to use the ID in the URL. I was thinking something like baseUrl/quote#/3/options (quote #3 options step). Currently the url looks like baseUrl/quote#/options. If I change the url in the .state definition from url: 'options', to url:':quoteId/options' it breaks my routes (can no longer get to the option step). Also this wouldn't work for a new quote since it doesn't yet have an ID. What's the best way to get this to work?
quoteWizardModule.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('wizard', {
url: '',
templateUrl: 'Scripts/templates/quoteWizard/wizardLayout.html',
controller: 'wizardNavigationCtrl'
})
.state('wizard.options', {
url: 'options',
templateUrl: 'Scripts/templates/quoteWizard/wizardOptions.html',
controller: 'wizardOptionsCtrl'
})
.state('wizard.newmodel', {
url: 'newmodel',
templateUrl: 'Scripts/templates/quoteWizard/wizardModel.html',
controller: 'wizardModelCtrl',
})
.state('wizard.model', {
url: 'model/:factoryId/:index',
templateUrl: 'Scripts/templates/quoteWizard/wizardModel.html',
controller: 'wizardModelCtrl'
})
.state('wizard.other', {
url: 'other',
templateUrl: 'Scripts/templates/quoteWizard/wizardOther.html',
controller: 'wizardOtherCtrl'
})
.state('wizard.customer', {
url: 'customer',
templateUrl: 'Scripts/templates/quoteWizard/wizardCustomer.html',
controller: 'wizardCustomerCtrl'
})
.state('wizard.shipping', {
url: 'shipping',
templateUrl: 'Scripts/templates/quoteWizard/wizardShipping.html',
controller: 'wizardShippingCtrl'
})
.state('wizard.notes', {
url: 'notes',
templateUrl: 'Scripts/templates/quoteWizard/wizardNotes.html',
controller: 'wizardNotesCtrl'
})
.state('wizard.review', {
url: 'review',
templateUrl: 'Scripts/templates/quoteWizard/wizardReview.html',
controller: 'wizardReviewCtrl'
});
}]);

Related

Angularjs ui-router state not working when new nested state added

I m new to angularjs and ui-router...I m facing hard time in solving issue
I have ui router configured.It works well upto two nested states but when i add new nested state ,it stop working.i cant figure out the reason,can some one point me what i miss??
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('settings', {
url: '/settings',
templateUrl: 'public1/settings.html'
})
.state('settings.profile', {
url: '/profile',
templateUrl: 'public1/profile.html',
controller: 'ProfileController'
})
.state('settings.account', {
url: '/account',
templateUrl: 'public1/account.html',
controller: 'AccountController'
});
.state('settings.login', {
url: '/login',
templateUrl: 'public1/login.html'
});
$urlRouterProvider.otherwise('/public1/profile');});
The end of your settings.account 'state', you have a semi-colon before the .state('settings.login ...
That's what's causing your error, I suspect.
Remove ";" from account state
.state('settings.account', {
url: '/account',
templateUrl: 'public1/account.html',
controller: 'AccountController'
})
.state('settings.login', {
url: '/login',
templateUrl: 'public1/login.html'
});

How to make URL simplier in UI-router

Here is my $stateProvider configuration:
.state('itemDetail', {
abstract: true,
url: '/itemDetail/general/:itemid',
controller: 'ItemDetailsController',
templateUrl: './partials/itemDetails.html'
})
.state('itemDetail.general', {
url: "",
controller: 'ItemDetailsController',
templateUrl: "./partials/itemDetails.General.html"
})
.state('itemDetail.file', {
url: "/file/:itemid",
controller: 'ItemDetailsController',
templateUrl: "./partials/itemDetails.File.html"
})
The user can look at item using #/itemDetail/general/96045 and can click the link to look at file attachments. Now it is work but URL for files now is #/itemDetail/general/96045/file/96045.
Is it possible to have URL for files as #/itemDetail/file/96045?
Well, I would go with one parent and only one child state. There is a working plunker
This will be the new one child state itemDetail.type:
.state('itemDetail', {
abstract: true,
url: '/itemDetail',
controller: 'ItemDetailsController',
templateUrl: 'partials/itemDetails.html'
})
.state('itemDetail.type', {
url: "/:type/:itemid",
controller: 'ItemDetailsController',
templateProvider: ['$stateParams', '$templateRequest',
function($stateParams, $templateRequest) {
var url = "partials/itemDetails.General.html";
if($stateParams.type === "file"){
url = "partials/itemDetails.File.html"
}
return $templateRequest(url);
}],
})
We are using here $stateParams.type to decide which template to load (and also $templateRequest to profit from angula built in caching)
And this will be the calling html:
<a ui-sref="itemDetail.type({type:'general', itemid:1})">
<a ui-sref="itemDetail.type({type:'file', itemid:22})">
The url will now look as expected
check it here
Yes it can be you need to give state as
.state('itemDetail.file', {
url: '/{itemId}',
controller: 'ItemDetailsController',
templateUrl: 'partials/itemDetails.html'
})

How to define multiple nested states with different parents but the same templates

i make an mobile site for buy/renew/transfer/ domains.
The whole app has 4 templates connected into functional chain.
Buy : Search -> (login if needed?) -> Pay -> -Confirmation
Renew : Choose -> (login if needed?) -> Pay -> -Confirmation
Transfer: Choose -> (login if needed?) -> Pay -> -Confirmation
While the app has the same templates, the functionality and titles are different. And i want to be able to check the parent state within every state in order to make dynamic changes, and switch request strings.
The simplest way is to define 12 (4X3) routes in my stateProvider. but i'm looking for more effective way to do this by unite buy.search, renew.search, transfer.search and others in three groups of routes. is it possible? Do any one may suggest me other approach?
Thanks
===UPDATE===
current stateProvider
.state('app.buy.search', {
url: "/search",
templateUrl: "templates/search_domain.html",
controller: 'SearchCtrl'})
.state('app.buy.login', {
url: "/buy/login",
templateUrl: "templates/login.html",
controller: 'LoginCtrl'})
.state('app.buy.pay', {
url: "/buy/pay",
templateUrl: "templates/pay.html",
controller: 'PayCtrl'})
.state('app.renew.search', {
url: "/search",
templateUrl: "templates/search_domain.html",
controller: 'SearchCtrl'})
.state('app.renew.login', {
url: "/buy/login",
templateUrl: "templates/login.html",
controller: 'LoginCtrl'})
.state('app.renew.pay', {
url: "/buy/pay",
templateUrl: "templates/pay.html",
controller: 'PayCtrl'})
.state('app.transfer.search', {
url: "/search",
templateUrl: "templates/search_domain.html",
controller: 'SearchCtrl'})
.state('app.transfer.login', {
url: "/buy/login",
templateUrl: "templates/login.html",
controller: 'LoginCtrl'})
.state('app.transfer.pay', {
url: "/buy/pay",
templateUrl: "templates/pay.html",
controller: 'PayCtrl'})
You can reduce the router configurations by applying dynamic url. In your case, pages (search, pay, login) are same for modules (buy, renew, transfer). So you can change the configuration as follows
$stateProvider
.state('app', {
url: '/',
templateUrl: 'dashboard.html',
controller: 'MainCtrl'
})
.state('app.search', {
url: '{module}/search',
views: {
"searchView": {
templateUrl: 'search.html',
controller: 'SearchCtrl'
}
}
})
.state('app.pay', {
url: '{module}/pay',
views: {
"payView": {
templateUrl: 'pay.html',
controller: 'PayCtrl'
}
}
})
.state('app.login', {
url: '{module}/login',
views: {
"loginView": {
templateUrl: 'login.html',
controller: 'LoginCtrl'
}
}
})
Demo: http://plnkr.co/edit/NGsZJB?p=preview

Ui-router using parent view but not as a layout

Hello when i have this states defined:
.state('locations', {
url: '/locations',
templateUrl: '/templates/locations/index.html',
controller: 'LocationsCtrl'
})
.state('locations.show', {
url: '/{location_id}',
templateUrl: '/templates/locations/show.html'
});
How can i have /templates/locations/index.html to show for example a list of all locations,
but templates/locations/show.html to show a view of the location, but not nested inside the view of index.html. Basically i want the routes nested, but not the views.
I just worked on an example similar to yours
.state('overview', {
url: '/all',
templateUrl: '_/partial/overview/all.html',
controller: 'homeCtrl'
})
.state('places', {
url: '/:id/place',
templateUrl: '_/partial/details/detail-place.html',
controller: function($scope, $stateParams) {
$scope.path = $scope.paths[$stateParams.id];
}
})
In your case
.state('locations', {
url: '/locations',
templateUrl: '/templates/locations/index.html',
controller: 'LocationsCtrl'
})
.state('show', {
url: '/{location_id}',
templateUrl: '/templates/locations/show.html'
});
That means the show state shouldn't be nested under locations.

Angular routing for different layouts

How do I load different layouts ?
Currently I have three layouts for my backend, one for admin, one for user and last for teacher i.e adminLayout.html, userlayout.html and teacherLayout.html for dashboards.
I am writing my routes something like this -
app.config(function($routeProvider){
$routeProvider
.when('/', {
templateUrl: 'views/pages/home.html',
controller: 'homeCtrl'
})
.when('/users/login', {
templateUrl: 'views/users/login.html',
controller: 'usersLoginCtrl'
})
.when('/users/dashboard', {
templateUrl: 'views/users/dashboard.html',
controller: 'usersDashCtrl'
})
.when('/teachers/login', {
templateUrl: 'views/teachers/login.html',
controller: 'teachersLoginCtrl'
})
.when('/teachers/dashboard', {
templateUrl: 'views/teachers/dashboard.html',
controller: 'teachersDashCtrl'
})
});
For /users/dashboard I want usersLayout.html and /teachers/dashboard I want teachersLayout.html.
How could I acheive this ?
I tried $window.location.href = "LINK_TO_LAYOUT"; but its is taking the whole path in the URL, however I want to my URL like -
mysite.com/teachers/dashboard
mysite.com/users/dashboard
mysite.com/admin/dashboard
You should use Ui-Router.
It support nested views.
So in your example your routes would be like this.
app.config(function($stateProvider){
$stateProvider
.state('main', {
url: '/',
templateUrl: 'views/pages/home.html',
controller: 'homeCtrl'
})
.state('users', {
url: '/users',
templateUrl: 'views/users/layout.html'
})
.state('users.login', {
url: '/users/login',
templateUrl: 'views/users/login.html',
controller: 'usersLoginCtrl'
})
.state('users.dashboard', {
url: '/users/dashboard',
templateUrl: 'views/users/dashboard.html',
controller: 'usersDashCtrl'
})
.state('teachers', {
url: '/teachers',
templateUrl: 'views/teachers/layout.html'
})
.state('teachers.login', {
url: '/teachers/login',
templateUrl: 'views/teachers/login.html',
controller: 'teachersLoginCtrl'
})
.state('teachers.dashboard', {
url: '/teachers/dashboard',
templateUrl: 'views/teachers/dashboard.html',
controller: 'teachersDashCtrl'
})
});
Then you need to creat this new Layout Pages.
On: views/users/layout.html
<div id="usersLayout">
<ui-view/>
</div>
On: views/teachers/layout.html
<div id="teachersLayout">
<ui-view/>
</div>
Hope this get you going.
One of ways use 'abstract' state from ui-router
$stateProvider
.state('contacts', {
abstract: true, // <<< this is your layout
url: '/contacts',
// Note: abstract still needs a ui-view for its children to populate.
// You can simply add it inline here.
// >>> Or use templateUrl: 'contactLayout.html'
template: '<ui-view/>'
})
.state('contacts.list', {
// url will become '/contacts/list'
url: '/list'
//...more
})
.state('contacts.detail', {
// url will become '/contacts/detail'
url: '/detail',
//...more
})
Please spend some time for learning ui-router and you will have powerfull and simple tool for routing in angularjs.
Check docs for more info about abstract state.

Resources