Implementing an EventBus in MooTools
An event bus can be useful in making your web applications more maintainable and manageable. It does so by decoupling the source of the application events from their destination. In complex web applications, a change in one part of the screen might require other parts of the screen to update as a result.
A big part of this manageability comes with using custom events that are closer to our domain model than ‘clicks’, or ‘mouseovers’. If you have any doubts about the usefulness of custom events, you might want to read this article first.
A very common example of such a custom event is user registration. Once a user registers on a site, and assuming they are automatically logged-in right after, then various parts on the screen will need to be updated as a result. A registration successful message pops-up somewhere. The navigation panel is updated with a Logout link. Other things that only registered users can do will get activated.
If your application is highly modularized into widgets, views, etc., then you might not want to create an unnecessary binding between those components just because they need to listen to a particular event that some other component happens to fire. All that a widget needs to know is that an event of interest has fired, regardless of the source (for most cases), and that it must respond to it. Ray Ran gives a nice example with a full walkthrough in his talk at Google I/O and explains how an EventBus solves the problem. I highly recommend watching the talk since the problem and solution that he demonstrates is very much applicable to any complex web application and not just apps written in Google Web Toolkit. An event bus acts as a central broker for communicating events to various parts of the application that need not know about each other’s presence. It basically publish-subscribe and somewhat similar to the NSNotificationCenter in Cocoa if you’re familiar with that.
Once you are thoroughly convinced that you absolutely need this, you would really like the solution too if you’re using MooTools. Why? checkout for yourself -
var EventBus = new Class({Implements: Events});
1 line. That’s all that you need to start using an EventBus. MooTools classes can already handle events by implementing Events in Class.Extras. All that is need is creating an object of a class that does this and passing it around to whoever needs is using dependency injection and each object can register and post their events to this event bus.
Here’s a small example that makes use of this event bus with a couple of different types of classes:
Here’s a tiny wrapper around the EventBus class above. All it does is change the names addEvent, removeEvent, and fireEvent to be a little more semantic with observers. Nothing fancy.Controlling a MooDialog of an existing element programatically
MooDialog is a very nice Javascript plugin for creating your own dialog boxes that are much better looking than the native confirms, alerts, and prompts. The plugin offers much more in functionality and can be used to create dialog boxes with an iframe’s content, ajax responses, and existing DOM elements among others.
Once created, these dialog boxes can be programmatically opened, closed, or disposed off. The online documentation is very well written, but it doesn’t mention how would you open or close a dialog that was created using an existing DOM element.
To create a dialog from an existing element, we would just call .MooDialog() on the element.
<div id="myElement">
...
</div>
$('myElement').MooDialog(); // that's all
However, since this method call simply returns myElement (for chaining purposes, I believe) and not the MooDialog object, we cannot call open() and close() on it. The plugin has a brilliant solution to take care of the problem - the Element store.
The dialog object is stored with the key “MooDialog” into the element store. So to get access to the dialog object for “myElement”, simply call retrieve(‘MooDialog’) on it.
var dialog = $('myElement').retrieve('MooDialog');
dialog.open();
dialog.close();
MooTools class keyword breaks in Safari
Having test the app in Chrome and Firefox, I happily strolled to Safari in a delightful mood only to find a blank page and JavaScript errors, yikes. After some digging on Google, I found the problem. Safari is not only backward compliant but forward compliant too. The class keyword that is very often used while creating an Element in MooTools is a future reserved keyword in ECMAScript language specification ECMA-262. Don’t believe me? Check it out for yourself at http://www.ecma-international.org/publications/standards/Ecma-262.htm
Not a huge problem and we have to quote the class keyword. So something like this:
var container = new Element("div", {class: "link"});
now becomes this. Note the quotes around class
var container = new Element("div", {"class": "link"});
And we’re good to go!