At the Forge - Dojo Events and Ajax
We can then tell the user's browser to invoke our openAlert function whenever someone clicks on a paragraph of text:
<p onclick="openAlert();">This is a paragraph.</p>
Second, event handlers sometimes can be used in contexts you might not expect. For example, the above <p> tag has an onclick handler. You normally wouldn't think of clicking on a paragraph of text, but we can do that. This is the basis for some of the modern drag-and-drop events.
As a simple example, let's see how we might implement our onclick handler from before using Dojo events. First, we need to modify our event-handling function so that it takes one argument, the event itself:
Next, we must connect the paragraph to the event. Rather than doing this directly, by setting the onconnect handler, we give our paragraph an id tag:
<p id="para">This is a paragraph.</p>
Now, we can use Dojo's dojo.byId function—similar in some ways to Prototype's $() function—to get the node itself:
var para = dojo.byId("para");
Finally, we connect our paragraph to the handler function we created:
dojo.event.connect(para, "onclick", openAlert);
If we put it all together, we get the program shown in Listing 1, which I have called test-dojo.html.
Listing 1. test-dojo.html
If you load the page into a browser window, you will see that it works just like the previous version. Given that this version is more complex, it might not seem obvious how it is better.
dojo.event.connect(eventObject, "onclick", handlerObject, "handlerMethod");
dojo.event.connect(para, "onclick", testFormContents); dojo.event.connect(para, "onclick", submitFormContents);
Events are fired in the order that they are connected. So, in the above example, testFormContents would be invoked before submitFormContents.
Note that Dojo allows you to add the same event handler twice, if you want. So, be careful to invoke dojo.event.connect only once for each event-handler combination to avoid potentially odd and hard-to-debug problems.
Let's say you want to provide an expert mode to your users, so they don't have to see all of the annoying alert boxes we're generating. We could create a button that, when pressed, removes the event handler from the object—ooh, but now that's getting kind of tricky, especially if we have multiple events to deal with.
The solution is to use dojo.event.disconnect, which does what you might expect:
dojo.event.disconnect(para, "onclick", testFormContents);
dojo.event.disconnect requires that the parameters be completely identical to those used in dojo.event.connect. Once it is invoked, however, the event is disconnected.
An advanced piece of the event system is known as advice, a term that always has confused me, but which is common in the worlds of Lisp and aspect-oriented programming. The basic idea behind advice is that you can tell the system to invoke a function before or after another function. (If you have used Ruby on Rails, this is analogous to a filter.) This is admittedly an advanced feature, but it might help when debugging an application—rather than inserting logging statements into a problematic function manually, you simply can add advice to the function, invoking the logger before or after the function is invoked.
There is even a topic mechanism for Dojo events, which lets you create multiple channels for event notifications. (This is similar in some ways to the syslog facility in Linux and UNIX.) Thus, a particular object might register its interest when particular events happen on another object.
Finally, Dojo events are used to give functionality to widgets—Dojo's name for GUI elements made up of HTML and CSS.
Listing 2 shows dojo-ajax.html, a page that contains only a single button marked “Press here”. When the button is pressed, the user sees an alert box, much as in Listing 1. But, in this version of the program, the contents of the alert box have come from a server-side program, defined in this case to be the very short hello.php (Listing 3).
Listing 2. dojo-ajax.html
Listing 3. hello.php
<? echo "Hello from the server!"; ?>
The button itself is defined as we might do with any button to which we expect to attach an event, with an id attribute. It sits inside of a very small HTML form, named “theForm”:
<form id="theForm"> <input type="button" id="theButton" value="Press here" /> </form>
Using Dojo events, we connect the button to a function (ajaxAlert):
Finally, our ajaxArgs object is bound, and we're off and running. Clicking on the button means the associated Dojo event is invoked, which is ajaxAlert. That function, thanks to dojo.io.bind, then sends its arguments to the defined URL and invokes the load function upon successful completion. This is surprisingly straightforward and opens up many possible avenues for using Ajax in applications.
The main source for information about Dojo, as well as Dojo software releases, is dojotoolkit.org. Documentation for the toolkit is still a bit sparse, but it has improved significantly in the last few months, and continued improvements seem likely, given Dojo's growing popularity. The main URL for Dojo documentation is at dojotoolkit.org/docs, and Dojo.book (the Wiki-based Dojo documentation) is at manual.dojotoolkit.org/index.html.
Finally, a noteworthy introduction to Dojo events is at www.dojotoolkit.org/docs/dojo_event_system.html.
Reuven M. Lerner, a longtime Web/database consultant, is a PhD candidate in Learning Sciences at Northwestern University in Evanston, Illinois. He currently lives with his wife and three children in Skokie, Illinois. You can read his Weblog at altneuland.lerner.co.il.