I am currently building a script which will notify the user that the form has been changed before they navigate away from the page (This is an ASP.NET MVC app btw).
I first started out building a simple script which detects if the user changes any inputs, and then flips a bit to designate the form as "Dirty".
This ended up being too simple and lacked support for extended form inputs, so I tried a plug in next.
The best one I could find was this: http://mal.co.nz/code/jquery-dirty-forms/
This jquery dirty forms plug in works pretty well, but still lacks one important feature which I require; the ability to compare previous values with what the user entered.
For example, if a text field originally has the value of "Foo Bar", and the user changes that value to "Foo" the form is now dirty.
When the user changes the value of that text box back to "Foo Bar", then using this plug in, the form is still "dirty", which is incorrect per my requirements.
There is no plug in that does what I need it to do, so I will have to build my own, which leads me to my question: what is the best practice for building this kind of functionality?
My idea was this:
- Since this app is MVC I could use the following tech:
- jquery
- json
- data annotations
My initial thought is that:
- The page can have many forms; each form will have an attribute "isDirty" initially set to false.
- I will need to store the original value for each field to compare (memento)
- Each field can have a class/flag/attribute "isDirty" which will call out that field "highlight, etc"
- I could store these field values in a JSON NVP data structure
- On Submit the JavaScript would walk through that JSON string and look at the orignal values, compare with the current value, if it is invalid then it would add a "Dirty" flag (append class name) to the text field which violates the dirty rules.
Performance and re-usability are definite considerations. I should be able to apply this pattern to any form, and with little work allow it to consume original values and perform validation.
Has anyone seen an existing pattern that is similar to my need? Does my idea sound viable? Does anyone have input on a better route I can take? Getting me started with a code sample I could extend would be fantastic, pseudo code would be good also.
[Update]
Someone just told me what I am trying to do is commonly known as a "form stash", though google doesn't help much with that search term.
This script which I have been working with is similar to what I want to do: (from this page: http://www.mydogboris.com/2009/10/using-jquery-data-feature-to-detect-form-changes/)
var formChanged = false;
$(document).ready(function() {
$('#my_form input[type=text].editable, #my_form textarea.editable').each(function (i) {
$(this).data('initial_value', $(this).val());
});
$('#my_form input[type=text].editable, #my_form textarea.editable').keyup(function() {
if ($(this).val() != $(this).data('initial_value')) {
handleFormChanged();
}
});
$('#my_form .editable').bind('change paste', function() {
handleFormChanged();
});
$('.navigation_link').bind("click", function () {
return confirmNavigation();
});
});
function handleFormChanged() {
$('#save_or_update').attr("disabled", false);
formChanged = true;
}
function confirmNavigation() {
if (formChanged) {
return confirm('Are you sure? Your changes will be lost!');
} else {
return true;
}
}