Skip to content

Instantly share code, notes, and snippets.

@lsmith
Created August 5, 2010 15:41
Show Gist options
  • Save lsmith/509910 to your computer and use it in GitHub Desktop.
Save lsmith/509910 to your computer and use it in GitHub Desktop.
<!doctype html>
<html>
<head>
<title>Test Page</title>
</head>
<body class="yui3-skin-sam">
<h1>Getting notification that a form is &quot;dirty&quot;</h1>
<p>This is an incomplete YUI 3.2 (post pr1) solution to monitoring whether a form has had any of its field values modified. It has only been tested against the given markup, and it doesn't address updating values programmatically.</p>
<form id="formId" action="">
<input type="text" name="text">
<br>
<input type="radio" name="radio" value="radio A" checked> A
<input type="radio" name="radio" value="radio B"> B
<input type="radio" name="radio" value="radio C"> C
<br>
<input type="checkbox" name="checkbox" value="checkbox A" checked> A
<input type="checkbox" name="checkbox" value="checkbox B"> B
<input type="checkbox" name="checkbox" value="checkbox C"> C
<br>
<textarea name="textarea"></textarea>
<br>
<select name="select">
<option value="select A">A</option>
<option value="select B" selected>B</option>
<option value="select C">C</option>
</select>
<br>
<input type="submit">
</form>
<script src="/dev/yui/yui3/build/yui/yui.js"></script>
<!--script src="http://yui.yahooapis.com/3.1.1/build/yui/yui.js"></script-->
<script>
YUI({
filter: 'raw'
}).use('node', 'event', function (Y) {
// TODO: this should be rolled into a synthetic event
var form = Y.one('#formId');
form.on('submit', function (e) { e.preventDefault(); });
form.setData('dirty', false);
form.setData('values', {});
// TODO: this should be abstracted out for generic form field value queries
function getValue(name) {
if (name) {
var el = form._node.elements[name],
val = [],
i;
if (el.tagName && el.tagName.toLowerCase() === 'select') {
el = el.getElementsByTagName('option');
}
if (el[0]) {
for (i = el.length - 1; i >= 0; --i) {
if (el[i].checked || el[i].selected) {
// assumes value attribute is defined for select options
val.push(el[i].value);
}
}
} else {
// might not get type=file changes
val[0] = el.value;
}
return val.join(',');
}
}
function checkDirty() {
//console.log('blur ' + this.get('value'));
if (!form.getData('dirty')) {
var name = this.get('name'),
values = form.getData('values') || {},
origVal = values[name],
val = getValue(this.get('name'));
delete values[name];
if (origVal !== val) {
form.setData('dirty', true);
// TODO: should probably detach event subscriptions
// TODO: should publish 'dirty' event as fireOnce with defaultFn
// to detach subs.
form.fire('dirty', {
field : name,
prevVal: origVal,
newVal : val
});
}
}
}
form.delegate('focus', function () {
//console.log('focus ' + this.get('value'));
if (!form.getData('dirty')) {
var name = this.get('name');
form.getData('values')[name] = getValue(this.get('name'));
}
}, 'input, textarea, select');
form.delegate('blur', checkDirty, 'input, textarea, select');
form.delegate('click', checkDirty, 'input, select');
form.on('dirty', function (e) {
console.log("Form is dirty due to " +
e.field + " BEFORE(" + e.prevVal + ")" +
" AFTER(" + e.newVal + ")");
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment