[web] JavaScript: Preventing user from leaving page

This topic is 4268 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I need to be able to stop a user from leaving a particular page (via a confirmation dialog - this is to prevent them from switching page without saving a form first). I can catch the page after it has been unloaded via the onunload event, but by that point the page has been unloaded so I don't have the form to save any more. I hear mention of onbeforeunload, but that event doesn't get fired for me. Is what I aim to do possible?

Share on other sites
Save the form using javascript as its modified (ie. store it in a cookie as its being typed, remove it when its sucessfully submitted, and get it back on page load)
Then make the page reload if it wasn't submitted right.

Share on other sites
Just a hint, don't "force" a user to do anything, nothing will iritate your users more then not being able to leave if they want to. If I am in the middle of filling out a form and realize I need to go do something else, and your page stopped me from leaving, I would NEVER return. You can save the data as the user fills out the form and that way you will not loose the information but please do not trap the user.

theTroll

Share on other sites
Quote:
 Original post by TheTrollJust a hint, don't "force" a user to do anything, nothing will iritate your users more then not being able to leave if they want to. If I am in the middle of filling out a form and realize I need to go do something else, and your page stopped me from leaving, I would NEVER return. You can save the data as the user fills out the form and that way you will not loose the information but please do not trap the user.theTroll

^^^ What he said.

Share on other sites
I don't think he's actually trapping them. Just asking them "Are you sure you want to leave?". That was my understanding at least.

Share on other sites
I've not discovered a way in order to do this. It seems like something a web browser should never let a script do. Think of a popup which never allows the user to close it.

Share on other sites
What I mean is a confirmation dialog - 'You have edited some information on this page without saving' - with an OK button to return to editing the page and a Cancel button to just skip onto whichever page you were moving to.

I've managed to get 'onbeforeunload' working in IE with the aforementioned dialog, but I'd really rather have a better cross-browser solution. I have:

var FormNeedsSaving = false;if (window.attachEvent) window.attachEvent('onload', formSave);window.onbeforeunload = checkFormSave;function checkFormSave() {    if (FormNeedsSaving) return "You are leaving the page without saving changes.";}

formSave is a function which goes through every 'control' element on any form with the 'form_save' style attached to it, and hooks in the onchange/onclick events required to set FormNeedsSaving to true (dirtying).

Share on other sites
If they are leaving the page via links on your site, here are some options:

1. Don't provide any links for them to leave the page via

2. Put onclick events on those links to ask them "are you sure" or similar. If you return false from an onclick event handler on an anchor, it will not follow the link.

Mark

Share on other sites
I'm pretty sure that the windows has an onclose event that can prevent the window from being closed. How do you feel about popups?

Share on other sites
Quote:
 Original post by markr2. Put onclick events on those links to ask them "are you sure" or similar. If you return false from an onclick event handler on an anchor, it will not follow the link.
I'll probably have to be that, in the end. Thanks, all!

Share on other sites
AFAIK, the onbeforeunload is only going to work in IE and FF. So if you need truly cross-browser compatibility, it is not the way the go.
If a user is navigating to another page on the same (your) site, you could notify the user there. In order to keep track of the modifications in the original form, you'll have to watch the form field for any changes and store the changed flag in a cookie, dynamically append it to the querystring of links in the document, or use some sort of httprequest system. And I bet there are may more options.

If you are prepared to use iframes, there may be another solution. Make sure that the document containing the form is embedded in an iframe. Navigating to some other page should also take place in that frame. The iframe itself doesn't have to look like it is a frame, you could just remove its borders, scrollbars etc.
In the page surrounding the iframe, you can now capture the onload event of the iframe. Onload is supported by pretty much all browsers, so you shouldn't have much problems with browser support. This event is fired when the new document is loaded, so you're still a bit too late, but you will have more control over it. :) You could either redirect the user to the previous page, or display a warning message. Because the page arround the iframe hasn't changed, it could also serve as a place to store any data you want, in a more or less persistant manner.
Of course, this will not prevent users from closing their browser completely, or navigation to a different website.

Share on other sites
I just realised that GMail does exactly what you want in the compose message section. (If you try to leave the page it'll ask you to save a draft) I did a quick scouting over the code but wasn't able to find anything besides the string that is prompted is located on line 1133 in function Yo(a,b) of ?view=page&name=js&ver=a74d2cf28820cd90.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>Test</title><script type="text/javascript">window.onunload = function(){	if (confirm('Save changes?'))		document.forms['form1'].submit();};</script><head><body><form name="form1" action="" method="get">	<input type="text" name="name" />	<input type="submit"></form><a href="http://www.gamedev.net">GameDev.net</a></body></html>