Reputation: 862
I have a wizard with multiple Steps. Let's say something like this:
Product > Address > Payment > Verify
On the /verify
step, the user buys something. If the user now presses the back button on the browser, he should go to the /product
step and not to the /payment
step. To do so, I want to change the browser history from /payment
to /product
so that he can buy more stuff.
I use angularjs 1.3.14
with enabled HTML5 mode and ui-router 0.2.10
. So the solution might use HTML5 history. but it would be nice if it also works for older browsers. But the support is nice to have.
Upvotes: 1
Views: 1912
Reputation: 474
I know this is old but to help others, what I do is call .replace()
before I call .path()
to set the location of the back button. So in your case I would do:
// some code in Payment controller...
// call .replace() to set the history to '/product'
$location.replace('/product');
// now change .path()
$location.path('/verify');
Now on the /verify
route, if the user presses the browser's back
button, it should take them to /product
route instead of /payment
.
One thing to mention is I that I do not know if this will work on older browsers but I can confirm it works in Chrome 66.0.3359.181
and Safari 11.1
Reference: Location.replace()
Upvotes: 0
Reputation: 862
The answer from stackg91 gives me the right idea. As I don't want to change the page to rechange it in the next moment, I listen on $stateChangeStart
. So I've done something like this (pseudocode)
obj.finishedStateListener = $rootScope.$on('$stateChangeStart', function (event, toState) {
if(statechange inside wizard) {
event.preventDefault();
obj.finishedStateListener();
$state.go(initState);
}
})
It is very important to save the return of the $on
function, as it gives you the possiblility to unregister the eventListener. If you forget to call it, you will end in an infinite loop.
Upvotes: 0
Reputation: 3741
In HTML5 you can manipulate with history object: https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history
Actually, you can modify only the last entry, with two options:
pushState()
- add a new state at the end of historyreplateState()
- change the last entry with new oneIt is supported quite well http://caniuse.com/#feat=history, but be careful with older IE.
Don't forget to use fallback as:
if (history.pushState) {
// your code with history manipulation
} else {
// your fallback code for older IE and others
}
Upvotes: 0
Reputation: 594
Ok so basicly you could use States for this
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
// setup an abstract state for the tabs directive
.state('product', {
url: "/product",
templateUrl: "templates/product.html",
controller: "productCtrl"
})
.state('Address', {
url: "/Address",
templateUrl: "templates/Address.html",
controller: "AddressCtrl"
})
.state('Payment', {
url: "/Payment",
templateUrl: "templates/Payment.html",
controller: "PaymentCtrl"
})
.state('Verify', {
url: "/Verify",
templateUrl: "templates/Verify.html",
controller: "VerifyCtrl"
})
});
In your Main Controller you can watch for Statechanges
$rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
if(from.name == 'verify' && to.name == 'payment'){
$state.go('product')
redirect example
}
});
dont forget to inject $state!
Upvotes: 1