What is the best way to track changes in a form via javascript?
Solution 1:
Loop through all the input elements, and put an onchange
handler on each. When that fires, set a flag which lets you know the form has changed. A basic version of that would be very easy to set up, but wouldn't be smart enough to recognize if someone changed an input from "a" to "b" and then back to "a". If it were important to catch that case, then it'd still be possible, but would take a bit more work.
Here's a basic example in jQuery:
$("#myForm")
.on("input", function() {
// do whatever you need to do when something's changed.
// perhaps set up an onExit function on the window
$('#saveButton').show();
})
;
Solution 2:
Text form elements in JS expose a .value
property and a .defaultValue
property, so you can easily implement something like:
function formChanged(form) {
for (var i = 0; i < form.elements.length; i++) {
if(form.elements[i].value != form.elements[i].defaultValue) return(true);
}
return(false);
}
For checkboxes and radio buttons see whether element.checked != element.defaultChecked
, and for HTML <select />
elements you'll need to loop over the select.options
array and check for each option whether selected == defaultSelected
.
You might want to look at using a framework like jQuery to attach handlers to the onchange
event of each individual form element. These handlers can call your formChanged()
code and modify the enabled
property of your "save" button, and/or attach/detach an event handler for the document body's beforeunload
event.
Solution 3:
Here's a javascript & jquery method for detecting form changes that is simple. It disables the submit button until changes are made. It detects attempts to leave the page by means other than submitting the form. It accounts for "undos" by the user, it is encapsulated within a function for ease of application, and it doesn't misfire on submit. Just call the function and pass the ID of your form.
This function serializes the form once when the page is loaded, and again before the user leaves the page. If the two form states are different, the prompt is shown.
Try it out: http://jsfiddle.net/skibulk/ev5rE/
function formUnloadPrompt(formSelector) {
var formA = $(formSelector).serialize(), formB, formSubmit = false;
// Detect Form Submit
$(formSelector).submit( function(){
formSubmit = true;
});
// Handle Form Unload
window.onbeforeunload = function(){
if (formSubmit) return;
formB = $(formSelector).serialize();
if (formA != formB) return "Your changes have not been saved.";
};
// Enable & Disable Submit Button
var formToggleSubmit = function(){
formB = $(formSelector).serialize();
$(formSelector+' [type="submit"]').attr( "disabled", formA == formB);
};
formToggleSubmit();
$(formSelector).change(formToggleSubmit);
$(formSelector).keyup(formToggleSubmit);
}
// Call function on DOM Ready:
$(function(){
formUnloadPrompt('form');
});