So, what is it really?
Dojo is quite a lot of things. It has a staggering amount of widgets, to begin with; Dialogs, Panes, Menus, WYSIWYG editors, Buttons, Color pickers, Clocks, Layout Managers and a host of other things- just in the widgets department. Then there’s the very handy encryption package, handy for hashing things coming to and from the server-side, the Drag-n-Drop package which works with nearly any element on the page, the essential Collections API with Java-like iterators and whatnot, and of course the powerful proper Ajax functionality with several bells and whistles of its own.
Apart from the sheer amount of functionality available in dojo, there are a few architectural differences compared to most other frameworks; Dojo uses namespaces. This means that dojo always includes the package names in an object reference. If I want use the very nice for-each loop function, for instance, I have to refer to is like this; “dojo.lang.forEach(listOfThings, myFunc);”, instead of just “forEach(listOfThings, myFunc);”.
I’m going to use the dojo API version 0.4.2 in the examples, since the upcoming 0.9 only has reached milestone 2 as of this writing.
Getting the right stuff and copying the right files to your server
However, when you download and unzip the “standard” dojo package (dojo 0.4.2-ajax), the dojo.js file is only the starting point, the kernel so to speak, of dojo. All real functionality exists – and exists only - in files under the src/ directory. Also, most widgets have a lot of template html files and images that they have to get at, so the short dance version of this point is; Copy everything.
Check the test to see how things are done
The biggest problem the dojo community faces (IMHO) is the lack of a thorough API documentation and walk-through examples. True, there’s a very useful (at least to the intermediate-level dojo hacker) API tool, and there are several good sites which give fairly up-to-date walk-throughs and examples in specific areas. But the really good bits can be found on the test directory which also ships with the standard package.
If you go to http://download.dojotoolkit.org/release-0.4.2/dojo-0.4.2p1-widget you’ll see two interesting directories; demo and tests. The reason I refer to the live URL at the dojo download site is that you might want to poke around at other (upcoming) versions. The demo directory contains a fair number of demos, which are neatly organized in the following sections; Demo Applications (Mail client, Text editor), Effects (Fades, Wipes, Slides, et.c.), Drag and Drop, Storage, RPC, Layout Widgets, Form Widgets and General Widgets (Buttons, Menus, Fisheye menus, Tooltips, et.c.). This is a good place to let your jaw drop a bit and get some inspiration.
But the really good stuff is found under the tests directory. Here you will find unit tests for almost all widgets, layout containers, graphics, and lots of other things you’ll find truly useful. The reason the tests are more useful is that they are short, focussed and sometimes even (drumrolll, please) commented! My recommendation is to check out tests/widget for test_ModalFloatingPane, test_Dialog and test_Menu2_Node for some basic examples on how to use dojo widgets. Although dojo is an Ajax framework, much of the truly sterling functionality it offers has little if anything to do with client-sever communication – as you will find out.
Your first dojo-page
Before you do the fancy stuff you’re surely shaking with barely controlled desire to do, it’s a good idea to get a minimal “template-page” up and running. Of course, you could just grab one of the tests files and change things about, but how fun would that be? Here is a minimal html-page to start with, happily snarfed from one of the Dialog tests and shortened a bit;
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd”>
<title>My first Dojo page</title>
bsp; function getResults(evt)
var name = dojo.byId(“inputname”).value;
dojo.byId(“namediv”).innerHTML = “<b>”+name+”</b>”;
dlg = dojo.widget.byId(“DialogContent”);
dojo.event.connect(“hider”, “onclick”, “getResults”);
<div dojoType=“dialog” id=“DialogContent” bgColor=“white” bgOpacity=“0.5″ toggle=“fade” toggleDuration=“250″ closeNode=“hider”>
<form onsubmit=“return false;”>
<td><input type=“text” id=”inputname”></td>
<td colspan=“2″ align=“center”> <input type=“button” id=“hider” value=“OK”></td>
The first thing that happens here is that we load the file dojo.js, where among other things the dojo.require function is defined. Then we call that require function for the things we really need in our page. We could have just added a lot of script statements to get pretty much the same effect, but what’s col with the require loader is that we can use wildcards to load a whole package at a time, for instance dojo.widget.*. This OK when doing happy testing, but in production it’s a good idea to only load what you need.
Note also that the package structure of dojo is the same as the file structure, and actually derives from it. This means that if you create subdirectories for your own dojo-derived widgets or whatever, you can use the loader for them as well.
Then comes a script section were we define the variables and setup function to use in the page, which are page-specific. We could have taken these out and put them in a separate file, which we then could load using the standard script tag. As long as it’s only a dozen lines or so, I actually prefer to have them in the html file, if the logic is tightly coupled (as in this case) to the nearby elements.
There are two function, one obvious
callback function, which reads the value of an input field, and copies that the value of another element on the page. The other function is a setup function which calls the first function when the form is closed. It does so using dojos own dojo.event.connect function, which is very powerful and requires an article in its own right, but for our purposes here it suffices to say that it hides any browser quirks, to make events simpler to work with.
The second part of the page shows the standard dojo way of declaring widgets, by adding a ‘dojotype’ tag inside the element, which defines the type of widget to be created for the element. Note also the tag ‘closeNode’, which defines which node controls calls to the hide() function of the dialog.
When the link is clicked on the page, the dialog is shown, and when the “OK” button is clicked the dialog is hidden and the getResults() function is called.