(function ($) { $.event.special.textchange = { setup: function (data, namespaces) { $(this).bind('keyup', $.event.special.textchange.handler); $(this).bind('cut paste input', $.event.special.textchange.delayedHandler); }, teardown: function (namespaces) { $(this).unbind('keyup', $.event.special.textchange.keyuphandler); $(this).unbind('cut', $.event.special.textchange.cuthandler); }, handler: function (event) { $.event.special.textchange.triggerIfChanged($(this)); }, delayedHandler: function (event) { var element = $(this); setTimeout(function () { $.event.special.textchange.triggerIfChanged(element); }, 25); }, triggerIfChanged: function (element) { if (element.val() !== element.data('lastValue')) { element.trigger('textchange', element.data('lastValue')); element.data('lastValue', element.val()); } } }; $.event.special.hastext = { setup: function (data, namespaces) { var self = this; $(this).bind('textchange', $.event.special.hastext.handler); }, teardown: function (namespaces) { $(this).unbind('textchange', $.event.special.hastext.handler); }, handler: function (event, lastValue) { $.event.special.hastext.check($(this), lastValue); }, check: function (element, lastValue) { if ((lastValue === '' || lastValue === undefined) && lastValue !== element.val()) { element.trigger('hastext'); } } }; $.event.special.notext = { setup: function (data, namespaces) { $(this).bind('textchange', $.event.special.notext.handler); }, teardown: function (namespaces) { $(this).unbind('textchange', $.event.special.notext.handler); }, handler: function (event, lastValue) { if ($(this).val() === '' && $(this).val() !== lastValue) { $(this).trigger('notext'); } } }; })(jQuery);