1

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.

0

4 Answers 4

1

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!

Sign up to request clarification or add additional context in comments.

Comments

0

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 history
  • replateState() - change the last entry with new one

It 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 } 

2 Comments

Does this work with angular and ui-router? I've read that it might cause trouble with the internal state of ui-router.
is this what you are searching for? stackoverflow.com/questions/23026685/…
0

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.

Comments

0

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()

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.