PDA

View Full Version : Resolved Warn if new data in form before leaving page



djr33
08-25-2012, 07:36 AM
I'm creating a data entry script and it will take some time to fill in all of the data. (This is for a research project, with lots of data per page.)

I would like to create a script that has the following features:
1. If any data is entered in the form, the page is aware of that. (If no data is entered, nothing should happen, no warnings.)
2. If the user submits the form, there should be no warning message.
3. If the user leaves the page (or refreshes), a warning should appear to inform them that doing so will lose all of their data entered in the form.

I know how to do this manually, but is there any easy way to set this up? Specifically I'm wondering about the onchange event for the form inputs-- if there are a lot of them, that's a LOT of cutting and pasting.

If there were an "onchange" event for a form that would be simple. Or a way to automatically attach an onchange event to all children of a given form. I'm not sure how to do either of those, though.

jscheuer1
08-25-2012, 08:02 AM
Using jQuery:


$('form *').change(function(){
//the keyword this will be the form element that's changed.
});

djr33
08-25-2012, 08:46 AM
Ah, so concise. Thanks! Looks like that should work, but I'll post back if I have any trouble.
(jQuery's already on the site, so that's easy.)

djr33
08-25-2012, 09:22 PM
This ended up working just fine. Here's the code in case anyone else needs something similar.

The only other tricky part was working out how to conditionally trigger a confirm dialog onbeforeunload-- any return statement triggers the dialog, so you must only return something if you want it. So return nothing if you don't want the alert-- as shown below.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test Page</title>
<script type="text/javascript" src="/path/to/jquery-1.3.2.min.js"></script>
</head>
<body>
<form action="" method="POST" onsubmit="formmodified=0">
<p>Test: <input type="text" name="test"></p>
<p><input type="submit" value="Submit"></p>
</form>
<script type="text/Javascript">
formmodified=0;
$('form *').change(function(){
formmodified=1;
});
window.onbeforeunload = confirmExit;
function confirmExit() {
if (formmodified==1) {
return "New information not saved. Do you wish to leave the page?";
}
}
</script>
</body>
</html>

The only limitation appears to be the restriction to only the default error message in Firefox, but that is a known bug/feature and in this case it's the right information. (But not, for example, if you were using this to inform someone that an Ajax request hadn't finished, or that a music player would stop playing, or that an upload would stop uploading...)

jscheuer1
08-25-2012, 10:16 PM
I'd probably do it like so:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test Page</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script type="text/Javascript">
jQuery(function($){
var formmodified = 0;
$('form *').change(function(){
formmodified = 1;
});
window.onbeforeunload = confirmExit;
function confirmExit() {
if (formmodified === 1) {
return "New information not saved. Do you wish to leave the page?";
}
}
});
</script>
</head>
<body>
<a href="http://www.google.com/">test</a>
<form action="" method="POST" onsubmit="formmodified=0">
<p>Test: <input type="text" name="test"></p>
<p><input type="submit" value="Submit"></p>
</form>
</body>
</html>

I like my code in the head if possible and without global exposure.

djr33
08-25-2012, 11:31 PM
Thanks, John. I don't often write my own things in jQuery, so I'm not sure I understand the difference of using jQuery(function($){. Do I need that?


The reason I put it in the body was to avoid any issues with trying to execute this before the form existed on the page. I wasn't sure, so I thought that was simple enough. Is this something I should worry about?

Regarding the global variable, I don't really care because this is the only thing on the page and the variable name is long enough it shouldn't easily conflict with anything else if I needed to combine it with something. But obviously you're right if this were a bigger page or meant for general distribution. Is there anything else I'm missing, though?

traq
08-26-2012, 12:17 AM
It's a variation on this:

Aliasing the jQuery Namespace
When using another JavaScript library, we may wish to call $.noConflict() to avoid namespace difficulties. When this function is called, the $ shortcut is no longer available, forcing us to write jQuery each time we would normally write $. However, the handler passed to the .ready() method can take an argument, which is passed the global jQuery object. This means we can rename the object within the context of our .ready() handler without affecting other code:

jQuery(document).ready(function($) {
// Code using $ as usual goes here.
});
Basically, it keeps $ (which is used by several JS libraries and often causes conflicts) out of the global scope, but allows you to still use it normally inside your block of jQuery code.

jscheuer1
08-26-2012, 12:39 AM
And it executes as soon as the document has been parsed, allowing code that would otherwise have to either be placed at the end of the page or executed onload to go in the head. And (used as I have there) it isolates the variable(s) inside it as well as the jQuery $ from global exposure. Overall, it's good form, makes the code usable on a wider variety of pages or this page should other code be added.

In short though, you don't have to worry about any of those things until there's a problem. But one never knows when that might be. That's why I tend to start with good form.


BTW - Doesn't work in Opera, it has no onbeforeunload.

djr33
08-26-2012, 01:43 AM
Thanks to both of you. Right, in this case as long as it's working at the moment it's fine. The page won't get more complex in the future. But I'll keep those points in mind-- little projects like this are also a great way to learn new things (like jQuery).

This page will be used only by me and my research partners, so I doubt any of us will be using opera. If so, I hope (for them) that they don't accidentally click a link after entering lots of data.... ;)