I have a form generated by <% Ajax.BeginForm() {} %>
which contains a lot of inputs and texareas.
When an input value change, I need to know about it
From jQuery Docs:
//This applies to whole form
$('#formID').change(function() {
alert('Form changed!');
});
And you could do like this to check only the inputs and have user notified, if they try to exit without saving changes.
var inputsChanged = false;
$('#formID input').change(function() {
inputsChanged = true;
});
$(window).unload(function() {
if (inputsChanged === true) {
alert('Would you like to save your edits before exiting?');
}
});
jQuery API .change()
I would do this with jQuery. It would be something like this (just a draft, you may need to add/change some code):
$(document).ready(function() {
$('#formId:input').each(function(key) {
$(this).change(function() {
$(this).addClass('dirty');
});
});
});
Then, before POSTing, check if there is a dirty input. You can even add some color by using the dirty css class.
EDIT: typo fixed 'changed' to 'change'
Resurrecting this old question because I thought of a simpler/better way. Instead of listening to events on the various inputs, you can serialize the initial form data, store it, and then serialize it again later and check if it's changed, like this:
var originalFormData = $('form#formId').serialize();
function checkFormChanged() {
if(originalFormData !== $('form#formId').serialize()) {
//it's dirty!
}
}
One additional advantage here is that if the user makes a change and then reverts it, this check will report the form as clean.
You could use jquery plugin dirrty for identifying form dirty.
https://github.com/rubentd/dirrty
In on("dirty") event set some global variable to true to identify form has changed.
Handle window.onbeforeunload
or $(window).unload()
event and get confirmation from user based on that variable value.
The advantage of this plugin is you can track back if form is changed to original values again using 'on("clean") event
The html controls include a property that holds the original value. You could compare this value with the current value to see if there have been any changes.
function getHasChanges() {
var hasChanges = false;
$(":input:not(:button):not([type=hidden])").each(function () {
if ((this.type == "text" || this.type == "textarea" || this.type == "hidden") && this.defaultValue != this.value) {
hasChanges = true;
return false; }
else {
if ((this.type == "radio" || this.type == "checkbox") && this.defaultChecked != this.checked) {
hasChanges = true;
return false; }
else {
if ((this.type == "select-one" || this.type == "select-multiple")) {
for (var x = 0; x < this.length; x++) {
if (this.options[x].selected != this.options[x].defaultSelected) {
hasChanges = true;
return false;
}
}
}
}
}
});
return hasChanges;
}
function acceptChanges() {
$(":input:not(:button):not([type=hidden])").each(function () {
if (this.type == "text" || this.type == "textarea" || this.type == "hidden") {
this.defaultValue = this.value;
}
if (this.type == "radio" || this.type == "checkbox") {
this.defaultChecked = this.checked;
}
if (this.type == "select-one" || this.type == "select-multiple") {
for (var x = 0; x < this.length; x++) {
this.options[x].defaultSelected = this.options[x].selected
}
}
});
}