Mar 29 2009
Custom event handling with Prototype
The maturity and development of JavaScript has certainly led to more efficient handling nowadays. Remember those days when IE and Netscape had different event handling mechanisms. Well, the event handling mechanism is still different in IE and non-IE browsers, the popularity of JS libraries like Prototype, jQuery, YUI have certainly helped the web developers to fill that gap. One of the main reasons I love to use these libraries (PrototypsJS especially) is that native event handling really sucks. Forget about custom events, just in order to implement event in unobstrsuive way without those libraries you would require to consider event objects differently for IE and non-IE browsers something like this:
document.getElementsByTagName("input")[0].onkeypress = function(e) {
// If no event object exists, then grab the global (IE-only) one
e = e || window.event;
return e.keyCode != 13; //Do nothing when Enter is pressed
}
Its just a simple tiny example but one can imagine the potential complexity that could arise in nowadays’ site with petty high use of JS.
I did know that custom event handling exist in Prototype but I believe in YAGNI and never realized its potential. But as I am working in a project with massive JS and Ajax use, finally I have seen and used how custom events can be used to invoke to control encapsulate built-in JS events and use them in quite a flexible way.
While searching on the web about thistopic I found some really nice articles.
This last article has tried to explain normal and cusom events as:
When we describe normal events to our peers as a series of interactions, we generally say something like “For this tab menu, I want to swap the colors, then change the message on ‘click’ of the tab.”. Or if that sounds too awkward. We’ll say “When the user ‘clicks’ on the tab, I want to swap the colors and change the message.”
I can see it swindling in your brain already. Sure enough, the first thing that would normally come to a scripters mind is…. “I’ll assign a ‘click’ event to the tab that fires a function which will swap the colors, then change the message”. Fair enough. That totally works and that’s the way most people do it.
A custom event in this same model can be something you, yes you, get to make up. Looking at our tab/click/swapColor/changeMessage illustration, we can easily turn this into an event called onTabChange. In return, anytime our tab menu changes state, we can notify our listeners/subscribers that this event occured; then do whatever the heck we want on the fly.
Just following the above explanation, I have come with a simple example: A test scenario where a check box determines whether to enable or disable the onchange events for elements with CSS like .input. When the checkbox is enabled, particular onchange event for particular elements are also enabled and vice-versa.
Here is the HTML Code:
<fieldset> <legend> JS Custom Events </legend> <div> <input type="checkbox" value="1" id="enableInputEvents" /> Enable events for text box and combo box<br/> </div> <div id="inputs_elements"> Text Box 1: <input type="text" id="textbox1" value="" class="input" /><br/> Text Box 2: <input type="text" id="textbox2" value="" /><br/> Select Search Engine: <select id="search-engine-selector" class="input"> <option value="">Go to</option> <option value="http://www.google.com">Google</option> <option value="http://www.yahoo.com">Yahoo!</option> <option value="http://www.live.com">Live</option> </select> </div> </fieldset>
And JavaScript code for firing custom events:
Event.observe(document, 'dom:loaded', function() {
$('enableInputEvents').observe('click', function(e) {
document.fire('CheckBox:Enabled', {checked: $('enableInputEvents').checked});
});
});
document.observe('CheckBox:Enabled', function(e) {
Event.stop(e);
if (e.memo.checked) {
console.log("all elements with CSS class input are ENABLED");
$$('.input').each(function(t) {
t.observe('change', function() {
alert(t.value);
});
});
}
else {
console.log("all elements with CSS class input are DISABLED");
$$('.input').invoke('stopObserving');
}
});
Custom event handling in Prototype is a bit different than other JS libraries. And CheckBox:Enabled is a special notation type for firing custom events. Prototype API call this notation as namespace:eventname o avoid custom event names conflicting with non-standard native DOM events such as mousewheel and DOMMouseScroll.
When the Checkbox is enabled
When the Checkbox is disabled






