One of the more subtle, but very useful form feedback tools, is to animate the background when a user has changed a field. This animation is mostly useful with 'text' typed inputs, however, there is a case to be made about 'textarea' as well. Today's article shows a singleton method that manages a highlight animation, triggered whenever a user changes a text field. The developer need only register the field and the ChangeHighlighter widget will take care of the rest.
Example 1: ChangeHighlighter Singleton
Core.Controller.ChangeHighlighter = (function() {
// local namespace
var _F = function() {},
_that = null,
_YUD = YAHOO.util.Dom,
_YUE = YAHOO.util.Event;
// public namespace
_F.prototype = {
/**
* Registers the input with this widget.
* @method register
* @param elem {Element} Required. The input element to listen on.
* @param conf {Object} Optional. Configuration options.
* @static
*/
register: function(elem, conf) {
var npt = _YUD.get(elem);
// valid input
if (npt && npt.type && 'text' === npt.type) {
var cfg = conf ? conf : {color: '#EE0'},
lastValue = npt.value;
if (! cfg.duration) {cfg.duration = 0.75;}
_YUE.on(npt, 'blur', function() {
var val = (cfg.trim && ''.trim) ? npt.value.trim() : npt.value;
npt.value = val;
if (lastValue === val) {
// no change, do nothing
}
// value changed, animate
else {
lastValue = val;
var obgColor = _YUD.getStyle(npt, 'background-color'),
anim = new YAHOO.util.ColorAnim(npt, {backgroundColor: {to: cfg.color}}, cfg.duration);
anim._onComplete.subscribe(function() {_YUD.setStyle(npt, 'background-color', obgColor);});
anim.animate();
}
});
}
else {
alert('ChangeHighlighter:add Error - Invalid input parameter provided.');
}
},
/**
* Registers the input with this widget.
* @method register
* @param elem {Element} Required. The form element to search.
* @param conf {Object} Optional. Configuration options.
* @static
*/
registerForm: function(elem, conf) {
var form = _YUD.get(elem);
// valid element
if (form) {
var npts = form.getElementsByTagName('input');
// iterate on inputs and register
for (var i = 0; i < npts.length; i += 1) {
if ('text' === npts[i].type) {
_that.register(npts[i], conf);
}
}
}
}
};
_that = new _F();
return _that;
})();
All the work is done inside of the static "Core.Controller.ChangeHighlighter.register" method, so that a closure can be leveraged each time the 'blur' event is subscribed to. The 'register' method requires two parameters: the input to listen on and an optional configuration. The configuration allows the developer to change the animation color, the duration, and whether or not the values of the inputs should be trimmed before comparing (this also requires that "String.prototype" has been extended with a trim method). A variable 'lastValue' is used to track the previous value of the input so that the 'blur' event callback knows that a change has occurred (this is why a closure is needed). Then inside the 'blur' event callback, the 'lastValue' is compared with the current value, and a color animation is fired if the values are not the same.
There is also a 'registerForm' method, which simply searches for 'text' inputs and then calls the register method for each. I avoided using any non-YUI methods for ease of use.
