Back button clears inputs on previous page

I’ve got a page flow which goes roughly like this:

  1. User fills out form

  2. User clicks submit form

  3. My controller takes them to a confirmation page, which lets them

    view their inputs and click submit if they’re really sure

The issue is that, instead of clicking the submit button in step #3, if the user

instead clicks their browser’s back button, they’ll be back on the original

submit button, the one displayed in step #2–and all of their inputs will

have been erased.

How to prevent this? I assume it has to do with setting headers,

but I don’t know how to do that with Yii.

Thanks!

Emily

I think that there is no easy solution.

The back button is simply going to the previous page, wich was blank when the user started to fill the fields.

You can, for example, save the data in session and then use this data to compile the form.

This has the problem that, if the user close the browser and then come back to the input page, he will find already compiled with his old data.

Anyway, from the server point of view, hitting "back" or writin the address of the previous page has no difference (or selecting this address from the cronology…)

My approach is to prepare a back button in the form, if the use wants to use his onw methods, he will be forced to retype everithing and learn to use the instrumen he find in the page

Hi there,

As zaccaria told you - this is really, really hard problem.

All because it clients (browser) specific case (mood) how it will process clicking on the Back button. I.e. if it will reload page from server / cache, if it will refill previously filled forms (some browser has such behaviour) etc. You haven’t even got sure if a JS / jQuery code included in such page will be re-executed (some browsers does not do this, when re-reading page from cache).

For example (a bit off-topic, but explaining the problem), if you use simple JS code:


window.location.reload()

for the link onClick event and click that link a few times, you will have a total mess in Firefox browsing history, as this browser is adding new position to history each time page is being reloaded (which IMHO is an absurd - this is still the same page and FF knows this, as it is responding for reload request; IE does not have such behaviour, if I’m not mistaken).

So, this example illustrates that there are many problems across browsers and this is one of biggest pains of web developers ever.

All I can recommend you here is to include your own back button, inside page content, and strongly advice your users (with clear, visible message) not to use browsers build-in back button - I seen such approach on some bank webpage and must admit that it is some kind of nice solution for this problem.

IMHO

When I have to deal with multiple forms and the data is relevant to the next steps I do set systems that ‘hide’ but not ‘submit’ data until the confirmation occurs.

One example of this scenario is one of my websites: http://www.torrenovarentacar.com - make a search and then try to select a car (don’t look the design, was client decision)

Another way to workaround the problem is by using wizards: http://www.techlaboratory.net/labs/SmartWizard/index.htm

Anyway, there my two cents.

One other thing you can do is implement some javascript event listener which detects if you’re trying to navigate away from the page - you may have seen this on some websites - it will basically pop up a javascript alert message advising the user to click OK if they want to navigate away, or click Cancel to stay on the page.

Thanks for all the replies. I’d prefer not to store variables in session, disable the Back button, or cause the Back button to given an alert. I want the Back button to do what it does by default (outside of the Yii framework); it delivers the page from the browser’s cache–with all of the form data intact.

Antonio, this looks promising:

Antonio > When I have to deal with multiple forms and the data is relevant to the next

Antonio > steps I do set systems that ‘hide’ but not ‘submit’ data until the confirmation occurs.

Can you be more specific, though? Are you simply saying the "action" method for the form is "get" rather than "post"?

:slight_smile:

Emily - one way possibly around this is to render the confirmation page in the same controller action and not redirect to a different action if the data passes validation. You must also ensure the form submits to itself, i.e. the form’s ACTION attribute should be blank or pointing to itself.

This way when you click the back button your form inputs should still be populated. I have a form that works exactly this way on one of my websites and I can confirm it does not erase the inputs upon clicking the back button (tested on IE8).

I assume at the moment your controller action redirects to another action - this way POST data is not carried forward in the headers.

When you deal with multiple forms and one is relevant to the next, this is what is normally call: wizards. This is why I posted to you possible javascript solutions.

Using a javascript wizard (there are some jquery plugins outthere) you actually ‘hide’ a layer that holds the contents of the first step, then goes to the next (imagine is the confirmation of the previous step, the only thing you need to code is the javascript function that handles the ‘next’ step, reads the values of the form and writes them on the next layer before it is displayed)… when user clicks ‘back’ it actually shows the contents of the previous layer and therefore, the whole form filled with values.

When user clicks ‘confirm’ or ‘end’ or ‘submit’ at the end of the wizard, is actually clicking the button that submits the form at the first layer.

(please, refer to the links I posted on my previous response… if you have firebug installed, you will see that I actually ‘hide’ literally the information before I post final decision -payment gateway)

Hope it helps you.

Hi Emily, sign for an Akismet API key :) , is a joke… this is an example on how to create a wizard. In this case they have used an accordion approach.

http://akismet.com/signup/#free

Thanks Antonio for all the suggestions! I’ll definitely have a look at how you implemented wizards. I have another open question on the forum – it deals more with temporarily enabling the browser’s caching, rather than a complex solution like wizards; it’s my first choice as I like to keep things simple, and I don’t like effectively disabling the user’s Back button:

If the perfect elegant solution arises, I’ll post it on that thread and this one. Thanks again! :slight_smile:

I figured out how to set browser’s caching on.

It works with the latest MSIE and FireFox. Place these lines just BEFORE any call to render():




$expires = 300;  // sec

header("Content-Type: text/html; charset: UTF-8");

header("Cache-Control: max-age={$expires}, public, s-maxage={$expires}");

header("Pragma: ");

header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT');



Thanks to everyone for the suggestions!

:D

Are you 100% sure that forcing pragma-cache in header will solve are your problems related to re-filling or not re-filling form contents after user click back button? As I recall from my earlier projects I had a few situations where keeping form contents after using back button was not handled properly and not related to cache as caching was turned off in browser in that particular situation.

Keep an eye of this problem, because even if you think it works now, it might sadly stop working in future. As I wrote above, browsers upon using next/previous buttons are really twisted organisms. I wouldn’t bet my life on it that filling form contents is only related to cache. Form autocomplete feature of browser or plugin has a lot to say in this situation, Beside, what would that browser do, if cache would be turned off? And it is being turned off among more and more users due to connections speed being faster (therefore leading people to desire of having always up-to-date content of viewed pages) and for the security reasons. Especially, when accessing pages in some multiuser places like airports, Internet cafes etc.

During last weekend, before I read your post, I was thinking about really crazy solution. Storing what user has entered in some temporal DB table, implementing AJAX function running in background and checking if form fields aren’t empty upon page load, refilling them if so and flushing DB temporal table, when user finishes whole process. But this is really hard to implement and what is more important - as I wrote earlier - developer can’t be sure if after using back button, browser will refresh page (some does not do this) causing onload function to fire.

Yes, I also thought of various insane solutions before realizing that programmers really are in love with complex solutions, but a simpler one is always superior.

Adding the headers has fixed the issue. The user can click the Back button and get the browser’s default behavior, which is to naturally cache pages. I add these headers ONLY when I want to explicitly grab pages from cache–which is very natural when someone is filling out a form.

I agree there’s a slight security concern – someone in an airport, etc. I guess I’m trusting my users are a wee bit savvier than that, and would know to remove all cached files if using a computer in a public place. :D

Antonio - that is a very good solution, however clicking the “back” button on the browser doesn’t take you back to a previous step, because it isn’t actually loading a new “page”. Is it possible to enable back button on browser for this type of form?