snikch/jquery.dirtyforms — Issue #8: Feature request: Allow user to revert a change
Author: dannyadair
Created: 2011-10-17 07:57:30+00:00
State: open

At the moment, change() automatically sets a field dirty. It would be nice to allow the user to revert a change, thus making the field clean again. If that was the last dirty field the form becomes clean itself:

In $.fn.dirtyForms():

```javascript
$(core.fields, this).change(function(){
// A changed field is not necessarily dirty: Compare current with default value/selection
var is_dirty = false;
var element = $(this).get(0) // corresponding DOM element
var type = element.type;
if (type == "checkbox" || type == "radio")
{
if (element.checked != element.defaultChecked) { is_dirty = true; }
}
else if (type == "hidden" || type == "password" || type == "text" || type == "textarea")
{
if (element.value != element.defaultValue) { is_dirty = true; }
}
else if (type == "select-one" || type == "select-multiple")
{
for (var j = 0; j < element.options.length; j++)
{
if (element.options[j].selected != element.options[j].defaultSelected) { is_dirty = true; }
}
}
if (is_dirty)
{
$(this).setDirty();
}
else
{
$(this).unsetDirty();
// When the last dirty element becomes undirty the form becomes undirty
this.closest('form').determineDirty();
};
});
});
}
```

which would need the helpers

```javascript
$.fn.determineDirty = function(){
// Call this on a form to make it determine (set/unset) its dirtyness
// depending on whether there is at least one dirty form field
var form = $(this);
var form_still_dirty = false;
dirtylog('checking if form is still dirty...');
$(':input', form).each(function(index, element) {
if ($(element).isDirty()) {
form_still_dirty = true;
return false; // break: one dirty element is enough
}
});
if (form_still_dirty)
{
dirtylog('form with id '+form.attr('id')+' is still dirty');
return form.addClass($.DirtyForms.dirtyClass);
}
else
{
dirtylog('form with id '+form.attr('id')+' is not dirty anymore');
return form.removeClass($.DirtyForms.dirtyClass);
}
}

$.fn.unsetDirty = function(){
dirtylog('unsetDirty called');
this.each(function(e){
$(this).removeClass($.DirtyForms.dirtyClass);
});
// Important: For performance reasons the form does not
// automatically determine if it is now not dirty anymore.
// If you're doing calls to unsetDirty() manually then
// call determineDirty() on the closest form when done.
}
```