December 24th, 2008 1 Comment »
Tags: , , ,

Category: Articles

How debugAtAllCosts Works (Or: A Quick Primer on Dojo’s Loaders)

On pages 19-20 of my book, you’ll notice a handy table of the various configuration switches you can pass to djConfig to customize aspects of the bootstrapping process.  A sidebar I’d like to have included (and will include in a future printing or update) involves some additional explanation about how the debugAtAllCosts option works, and incidentally, explains some important nuances between the “normal” loader and the XDomain loader in the process.

At a glance, debugAtAllCosts is simply what you use to try and get some more specific debugging information when something has gone wrong and Firebug or Firebug Lite aren’t giving you much to work with. Oftentimes, a quick update to djConfig with debugAtAllCosts:true is all it takes to get that helpful information and isolate the issue.

But how does it do that?

Detour: A Primer on the Loaders
To better understand how debugAtAllCosts works, it’s critical to first understand the difference between the “normal” loader and the XDomain loader. (Recall that the XDomain loader works around the same origin policy and is used to bootstrap the toolkit from a domain that’s different from where your web page is located to bring your page to life with Dojo goodness e.g. AOL’s CDN and such things.) To illustrate, consider a simple HTML page that might have a script block in it that looks something like this:

dojo.require(“A”);
dojo.require(“B”);
dojo.require(“C”);

In the general case when the “normal” loader is being used, each of those three dependencies is evaluated synchronously such that the scripts for A, B, and C are each fetched in turn, and any dependencies are processed in a depth-first search fashion. For example, if B had dojo.require’d modules named D and E (in that order), then the overall order of requests look like A -> B -> D -> B -> E -> B -> C. Note that B is listed multiple times in that chain because B begins loading, then at some point (maybe immediately) D is processed, then E is processed, and then control returns to B one last time before C gets kicked off.

It’s worth reiterating is that the execution of D and E are “blocking” in the sense that B begins executing, then when the dojo.require(“D”) statement is reached within B, D is processed on the spot before B finishes executing; ditto for the way that E works.

With the “normal” loader, the entire process is entirely predictable every single time. You can not only count on the dojo.require dependencies being resolved properly, but you also have an implicit guarantee about the relative order of various dojo.require statements that appear sequentially in the same source file as in the previous example.

The XDomain (cross-domain) loader, however, does something different by necessity of the way it circumvents the same origin policy, which can’t be done with dojo.xhrGet. It uses information provided through other djConfig switches such as baseUrl and modulePaths, or uses information provided via the dojo.registerModulePath function to build URLs that serve as the SRC attribute for dynamically insert SCRIPT tags that get inserted into the HEAD of the page. Moving forward, realize that the dynamic insertion of SCRIPT tags is an operation that is asynchronous in nature.

One of the most significant differences to note is that while dojo.require dependencies are still preserved by the XDomain loader, the relative order in which non-dependent modules become ready (where “ready” roughly corresponds to “alive” or “fully processed”) is not necessarily preserved. In our working example, this means that while the XDomain loader guarantees that D and E will be ready before B is ready, it guarantees nothing about whether D will be ready before E or if E will be ready before D — nor does it guarantee anything about the relative order of A, B, or C becoming ready. The reason why there are no such guarantees is simply due to the nature of asynchronous requests and latency.

To make sure you fully grasped the important nuances in that paragraph, here are a few of the possible scenarios with the XDomain loader for our toy example:

D -> E -> B -> A -> C
A -> C -> D -> E -> B
A -> C -> E -> D -> B
E -> A -> D -> C -> B

Note that in all scenarios, both D and E are ready, in no particular order, before B is ready. That’s the only commonality.

If you stop to ponder for a moment, you’ll recognize that a really easy way you could not only get into trouble but also cripple yourself from trivially porting your application to take advantage of the XDomain loader would be if you constructed logic that depended on the relative order of modules loading. For example, if you were counting on module A in the working example to perform a synchronous dojo.xhrGet request to retrieve some kind of global object that gets used throughout your application and module B, C, D, or E relied on it, you’d have a race condition on your hands if you tried to go with an XDomain build because there’s no guarantee that A will finish loading before any of the other modules; maybe it will, but maybe it won’t. For XDomain loading scenarios, if you truly wanted to guarantee that A would load before every other module, you’d have to go as far as to identify A as a dependency such that everything else that needs to block on it would block on it.

Getting Back to How debugAtAllCosts Works
Getting back to debugAtAllCosts and how it does what it does — basically, it forces the XDomain loader into effect, which causes each module to be individually loaded via a dynamically inserted SCRIPT tag as opposed to building up the equivalent of what’s analogous to a deeply nested parse tree that causes the underlying JavaScript engine to “just crap out” and give you a nearly useless error message when the going gets tough. Thus, while it can often work wonders and help you find some kinds of errors in a hurry because of the way it loads individual modules in isolation, it can also complicate your situation (for reasons that should now be obvious) if you haven’t been precise in identifying dojo.require dependencies or  are relying on the relative order or modules loading.

And as Paul Harvey would say, “now you know…the rest of the story.”

November 13th, 2008 Comments Off
Category: News

Ajax Bootcamp in January and May

Just a while ago, the Big Nerd Ranch had a slot open up in January, so I quickly snatched it up in hopes of an earlier-than-May rendition of the Ajax Bootcamp I’ll be teaching later in the year. They’re doing some interesting things out at the ranch (like building an entire ranch from scratch!), and you can keep up with it on Aaron Hillegass’s personal blog.

November 10th, 2008 1 Comment »
Tags:

Category: Vetted Links

OSCON ’08 Video Interview

I just noticed that sometime last week, a video interview where I talk about Dojo was added to my book’s catalog page. Aside from mispronouncing MochiKit (a colleague told me just a few weeks ago that it’s really supposed to be pronounced mo-chee-kit, not mo-key-kit) and briefly losing my train of thought in trying to explain the parameters of dojo._Animation (note to self: review 4th grade math book), there may be some good details in there if you’re new to Dojo.

November 10th, 2008 Comments Off
Tags: , ,

Category: Vetted Links

Read It on Google Books

It just occurred to me that it was worth pointing out that Google Books offers a limited preview of my book, which may be hady if you need to look something up, don’t have your paper copy nearby, and for some reason didn’t opt to buy the full PDF version of the book from the O’Reilly catalog. Interestingly, it seems that you can read a lot more of the book on Google Books than on the Safari preview; go figure.

Of course, there are plenty of torrents out there too if you’re more in the stealing mood, but I would point out that you’d probably be at a light disadvantage if you were that desperate, because there was a second print run last month that corrected known errata at the time. The old pirated versions of the book may not be easily distinguishable from the updated version, and well, I wouldn’t want you to blame me for b0rken code examples or anything, so I’d encourage just purchasing the PDF from the catalog.

Actually, it’s somewhat unclear to me if Google Books updates their data with newer printings, so you may just want to opt for the O’Reilly PDF if you start finding the electronic version handy enough that you access it more than a few times a day.

November 8th, 2008 Comments Off
Tags: , ,

Category: Vetted Links

Fat Dan’s (Dojo-powered) Casino

Not too long ago, I helped O’Reilly Media with a little project involving the creation of a roulette game and a slot machine to support one of their Head First books. You can check out the hosted version of these games over at Fat Dan’s Casino.

Looking back, I feel like using sprites for the slot machine icons as opposed to using separate z-axis layers would have been a lot cleaner, but this didn’t occur to me until after the fact. This implementation detail is somewhat of a moot point since it doesn’t affect the UX, but I thought I’d mention it in case you decide to hack on the code a bit.

Also, if you’re running IE, be warned that if you don’t have Silverlight installed, the roulette wheel isn’t quite as nice as it could be because VML is the default renderer and it — well, the performance characteristics of IE’s VML implementation could be a lot better. Comparing a simple operation like spinning an image using IE’s VML to Safari’s SVG is just mind-blowing.

Have fun over at the casino.

September 29th, 2008 1 Comment »
Tags: ,

Category: News

Dojo Developer Events at TAE

I’ve been in Boston attending and presenting at the Dojo Developer Day events as part of The Ajax Experience, and it’s been a blast so far. Here’s a quick summary of what’s been happening in case you couldn’t make it but want to say in the loop.

Sunday – Contributor/Committer Day at IBM

Yesterday, active members of the Dojo community got together to discuss strategic and tactical project management topics, the next release, heated architectural and design issues, and so forth. This was the first community event in which Peter Higgins reigned as the new project lead, and it was great to see him (masterfully) interacting with the project community.

There were also a number of other great announcements and discussions:

  • Dylan kicked off the day with a brief introduction and overview
  • The Dojo Campus site is launching really awesome online documentation that makes putting Dojo to work a lot easier than it has been before
  • The Dojo Foundation is hard at work fostering new projects and has a great new website on the way that makes the foundation, its projects, and its goals more accessible and easily digestible
  • The dojotoolkit.org site has a fantastic redesign on the way that you should expect before the end of the year
  • The Google Summer of Code students accomplished some really great work over the summer – hot animation fx that will be included in the imminent 1.2 release and 3d gfx are a couple of the projects I’ve followed most closely.
  • There’s a new build tool that Dustin Machi from SitePen is working on that will allow you to create a custom Dojo build on the fly through a web-based interface. From what I understand, ShrinkSafe will still have it’s place, but this new tool will make a lot of things quite a bit simpler (and way faster) for many use cases
  • Jon Ferraiolo gave a talk about happenings with the OpenAjax Alliance. So many interesting things are going on, including efforts to produce standards for Ajax IDEs so that code completion becomes easier and specific toolkit standards can be seamlessly bridged with OpenAjax standards, standards for widgets (primarily the kinds that are used in mashups and “mega-widgets” sort of like Google Gadgets) are continued to be spec’d out, and a lot of neat things in the mobile Ajax arenas and at play
  • There was a fierce round of lightning demos around lunch where many different presenters got 5 minutes each to demonstrate apps that they’re working on that employ Dojo
  • There were a number of breakout sessions in which small groups got together and had the opportunity to hack on code, discuss project issues, etc.
  • We ended the day by heading out to a nearby pub for some good beer and conversation over dinner.
  • I headed back to the hotel early to polish my slides for my talk the next day on gfx and fx with Dojo — a new and improved version of my OSCON presentation.

The short version of that story is simply that the day was a great time to interact with, program alongside, and pass some time with first-class JavaScript hackers. You’ll hear me say time and time again that the Dojo community is so much fun, and today was just one more testament to that being more true than ever.

Monday – Community Day at TAE (Renaissance Waterfront Hotel)

We kicked off the day bright and early at 8am sharp and had a “sold out” audience with standing room only. A brief rundown of the day’s events:

  • Dylan opened things up and got the day rolling
  • Peter presented on “progressive Dojo” and did some on-the-fly coding
  • I presented on gfx and fx with Dojo; slides and sample code will be posted here soon.
  • Tom Trenka did a guided tour of DojoX and showed off some of the state-of-the-art
  • Nikolai Onken demonstrated some tricks of the trade with layout dijits
  • James Burke presented on the build system
  • Peter took back the reigns and provided some demonstrations on Dijit
  • Another fierce round of lightning demos ended the day’s events at 1pm sharp

From what I understand, everyone signed docs that allows TAE to post videos of our talks whenever the video editing is complete, so I’ll post back here if/when that happens.

At this point, we’re all hanging out in the various lobbies hacking on code and otherwise intermingling until it’s time to head out for dinner and beer at the Summer Shack on 50 Dalton St here in Boston at 8pm.

I’ll be sticking around until tomorrow afternoon, so ping me if you want to get together.

September 15th, 2008 8 Comments »
Tags: , ,

Category: Screencasts

A Simple, Degradable Reflection Widget

A nice, shiny apple

Dojo makes creating a reflection of a nice, shiny apple like this one quite easy!

This post is the first of many screencasts for this site, so please bear with me as I get more skilled at producing video, developing my big boy voice, and those sorts of things. I’ve chosen QuickTime’s H.264 format as my default for screencasts, but if there are other (or better formats), I can always re-encode or provide alternatives. Just let me know!

Viewer discretion is advised.

Reflection has been in vogue for a while now in user interfaces, and it wasn’t long ago that I saw a headline about a JavaScript library that streamlined a number of useful effects such as reflection — but alas, without the benefit of Dojo. Well, being the Dojo fanboy that I am, I immediately started to ponder how to accomplish some of these same effects using the dojox.gfx module, and a couple of hours later, I had prototyped a nice, degradable widget that seemed to do the job. By the way, that’s one of the things I love so much about Dojo: once you have a reasonable grip on it, you seldom, if ever, have to look somewhere else. More times than not, a great deal of your work is already done for you, and you just have to connect some of the dots. Remember: it’s all about the frameworks

But there’s always a catch: in this case it’s that IE users must have Silverlight installed for the widget to work; otherwise, it degrades back to the plain image. The reason is that VML, IE’s default gfx renderer, doesn’t support transparency in gradients. No transparent gradient, no nice fade out effect. Likewise, if JavaScript is not available (honestly, who does that?), it degrades down to the bare image. If you didn’t already know, the gfx module exposes an API that works across browsers by using whatever drawing engine is available. At the moment, renderers are available for canvas, VML, SVG, and Silverlight. That pretty much covers it. Adding support for another one should be straightforward: follow the API guidlines and write it.

Watch the Screencast

I’ll briefly step through some of the interesting slivers of the widget in the next section for those readers who want to skim a written synopsis and put it to work right away, but those of you who have a the time and inclination to have me talk you through it should watch the screencast (~26M, mov file.) I don’t particularly cover basic aspects of the widget lifecycle or anything like that in this post, so if you’re interested in some screencasts on those kinds of basics, please leave a comment and let me know.

Skim the Synopsis

So you’re still reading…alright, once you download the example code, you should be able to unzip the archive, open up the html file, and everything should just work. Well, unless of course you’re using Internet Explorer and don’t have Silverlight installed. Unfortunately, it doesn’t appear that VML supports transparency in gradients (the very mechanism which gets us the faded out reflective effect), so there’s not a lot that we can do there. But the good news is that it’s degradable, so the image will appear as usual on IE.

The markup required to put it to work is simply something to this effect:

<img id="apple" dojoType="dtdg.ImageReflector" src="apple.png" />

And just like any other Dojo widget, you could opt to create it programmatically with something to this effect:

var niceShinyApple = new dtdg.ImageReflector({/* props could go here */}, "apple");

If you take a look under the hood, you’ll see that it’s surprisingly simple to pull this off. First, you create a surface to draw on that is some fraction of the image’s height and place this surface just below the image itself. Then, just draw a reflection of the (clipped) image on the surface using the standard 2D matrix transform for reflection and apply a linear gradient that becomes more transparent as it approaches the bottom. That’s really it. The rest is just a little bit of software engineering.

But do note that this would be a lot harder if the dojox.gfx API (yes, it says that it’s version 0.9, but it’s up to date as far as I can tell) wasn’t so fricken’ awesome. Serious kudos to Eugene Lazutkin and all of the committers who have worked so hard on making it this good. Having full-blown 2D matrix operations at your fingertips in such an accessible way for arbitrary backends is so powerful.

Download the Goods

Just in case you weren’t paying attention, you can use the links in this very sentence to download the example code and download a copy of the screencast (to watch in the privacy of your own home.)

Leave Feedback

Again, this is my first screencast, so if there are things that you particularly liked or things that I can do to make the next one a lot better, please leave a comment and let me know!

September 14th, 2008 Comments Off
Tags: , , ,

Category: News

Dojo is now at the Big Nerd Ranch!

This is just a quick note to mention that I now have a JavaScript/Ajax Bootcamp class offered out at the Big Nerd Ranch. We’re still ironing out some of the initial scheduling details, but there should be some definitive dates squared away pretty soon; I’ll post back here with an update when we get that all hashed out.

And yes, as you’ll notice on the course syllabus, I do plan to lean on Dojo heavily for most of the instruction even though the course wasn’t called something more like “Dojo Bootcamp.”

In case you’re not familar with the Big Nerd Ranch, it’s a really cool concept: the idea is that you go into a retreat setting and totally immerse yourself in a particular area of knowledge for the week. You get first class accomodations and meals, and unlike other training courses right in the middle of hectic metro areas where it’s far too easy to get distracted, you get more of a serene, tranquil setting. Plus, the proprietor of the Big Nerd Ranch, Aaron Hillegass (perhaps better known as “the guy who wrote the Cocoa book“), is a heck of a good fellow and has really cool hair hidden underneath the hat — unlike, some of us, who, uh, don’t have any hair…at least not at the moment.

September 10th, 2008 5 Comments »
Tags: ,

Category: Articles

Using Dojo: The JavaScript Toolkit with Industrial Strength Mojo (Linux Journal Reprint)

This post is a “reprint” of a feature article I wrote for the July 2008 edition of Linux Journal, entitled “Using Dojo: The JavaScript Toolkit with Industrial Strength Mojo.” The article text was minimally adpated from the printed form, so no extensive hyperlinking or web layout has been done. Per my contract with Linux Journal, the article must be published under a FSF Free Documentation License if I reproduce it, so I hereby republish it under the BSD Documentation License. (*Strikes Gavel*) Enjoy.

See the upper right corner

July 08 Cover

Featuring a rich standard library, an extensive collection of turn-key widgets, a unit-testing framework and build tools for minifying your source files, it’s no wonder that Dojo is a key part of products from industry giants, such as AOL, Sun Microsystems, BEA and others.

A number of JavaScript toolkits have emerged to automate common Web development tasks and simplify creating rich user interfaces. Of all the contenders, Dojo stands out as the industrial-strength JavaScript toolkit because of its incredible depth and breadth. It features an extensive JavaScript library, a system of rich turn-key widgets, a collection of specialized subprojects, build tools and a unit-testing harness. Regardless of what your project entails, it is almost a certainty that Dojo can simplify the development and maintenance required. This article systematically focuses almost exclusively on some of the most fundamental constructs in the toolkit’s highly optimized kernel, commonly referred to as Base.

Figure 1. Toolkit Architecture

Figure 1. Toolkit Architecture

Dojo: The JavaScript Toolkit You’ve Always Wanted

Variations among Web browsers have made developing applications for the Web really messy work. Working around subtle variations in JavaScript implementations, wrangling the Document Object Model (DOM) and normalizing content rendering across browsers can be downright tormenting at times, and unfortunately, a nontrivial portion of the investment in developing a solid Web application is spent re-inventing this kind of brittle boilerplate. Although many technologies have evolved to mitigate these kinds of issues, one you especially should be aware of the next time you decide to build a Web application is Dojo, the industrial-strength JavaScript toolkit.

In short, the Dojo toolkit is a liberally licensed client-side technology that can supplement virtually any aspect of Web development. It features a tiny but fully featured JavaScript standard library that insulates you from the bare metal of the browser, a large subsystem of widgets that snap into a page with little to no JavaScript required, and a suite of build tools for minifying and consolidating resources as well as writing unit tests. Knowing that industry giants, such as AOL, IBM, BEA and Sun Microsystems, are on board with Dojo should give you a boost of confidence if you’re leery of trying something else in an ecosystem that’s littered with half-baked inventions that don’t always come though on their promises to deliver all-encompassing solutions. This remainder of this article works through the bulk of the toolkit’s most fundamental JavaScript programming constructs that will benefit you regardless of the size or scope of your project.

Firebug

The Firebug add-on for Mozilla Firefox is a terrific tool that can benefit your Web development efforts in ways you can’t even imagine. Of particular interest is its console, which allows you to execute arbitrary JavaScript code–great advantage when learning a new technology, as you’ll commonly want to test out new ideas in an interactive fashion.

Getting Dojo To Work In Less Than One Minute

Although you could download Dojo from its official Web presence and set up a local installation, the easiest way to get started with Dojo is to use the latest version of Dojo that is hosted on AOL’s Content Delivery Network (CDN). The following page skeleton demonstrates that the minimal effort required to put Dojo to work from the CDN is a SCRIPT tag that loads Dojo into the HEAD of the page; it is especially noteworthy that the SCRIPT tag incurs the cost of one request to the Web server that delivers a gzipped payload of approximately 29kB and provides the latest 1.1.x release that is available. In Dojo parlance, the good that the SCRIPT tag provides is called Base, because it provides the base for the toolkit, and because everything you’ll use is contained in the base-level dojo.* namespace. Speaking of which, with the exception of the dojo identifier itself, the global page-level namespace is otherwise preserved:

<html>
    <head>
        <title>Putting Dojo To Work</title>

        <!-- Loading Dojo requires only one SCRIPT tag -->
        <script type="text/javascript"
            src="http://o.aolcdn.com/dojo/1.1/dojo/dojo.xd.js">
        </script>

        <script type="text/javascript">
            dojo.addOnLoad(function() {
                /* safely use any code that relies on dojo.*
                   functions in here ... */
            });
        </script>
    </head>
    <body>
        <a href="http://dojotoolkit.org">Dojo</a>
    </body>
</html>

To summarize, the dojo.addOnLoad block fires once the asynchronous loading of the dojo.xd.js file and any dependencies specified via dojo.require statements (more on these in a bit) have completed, and this is necessary in order to prevent any race conditions that might occur without it. Basically, the dojo.xd.js file providing Base accomplishes feats such as normalizing DOM events and provides you with a number of useful utilities for accelerating application development.

Fetching Nodes

As a natural starting point for our discussion, consider the following snippet from a Web page:

<form name="foo" action="/bar">
  <label>A form with name="foo"</label>
</form>

<div id="foo">
  A div with id=foo
</div>

The excerpt is trivial, and it should be obvious that running a function as simple as document.getElementById("foo") would always return the DIV element as a result. As a Linux user, you even could use a Gecko-based browser, such as Firefox, or a KHTML-based browser, such as Konqueror, to test the page and verify it for yourself. However, you may be alarmed and shocked to learn that running the very same test in Internet Explorer versions 6 or 7 returns the FORM element instead of the DIV element! This particular bug arises, because the name and id attribute namespaces are merged for IE. As it turns out, the DIV would have been returned if the FORM had not appeared first in the document, so this bug is especially tricky. At any rate, Dojo provides the dojo.byId function that works just like document.getElementById–except that it accounts for this particular issue. Use it to stay safe and to save some typing.

Manipulating Arrays

Although the Array data type is one of the most commonly used, not all arrays are created equal–at least not among the various JavaScript implementations. Fortunately, Dojo’s Array facilities provide an easy-to-use abstraction, ensuring that the code you write will work anywhere, and you won’t be left scratching your head staring at a big semantic bug that’s painful to track down. Consider the following (seemingly innocent) block of code:

var a = getMetasyntacticVariables();
if (a.indexOf("foo") != -1) {
  /* do something... */
}

Although you might swear that there couldn’t possibly be anything wrong with that code, that’s because you’re probably (again) using and testing with a nice KHTML- or Gecko-based browser. The Trident-based Internet Explorer has its own notions of what an Array should and shouldn’t do, and the indexOf method isn’t one of them. In other words, you can expect for your code most likely to outright fail if you try to invoke the indexOf function on an Array when the code runs in IE. In this particular case, you could use the dojo.indexOf function to produce code safely that is portable across browsers:

var a = getMetasyntacticVariables();
if (dojo.indexOf(a, "foo") != -1) {
  /* do something... */
}

Other useful Array methods available via the dojo.* namespace include map, filter, every, some, lastIndexOf and forEach. They all work as described in the Mozilla Developer documentation.

At first glance, the forEach method may seem a bit redundant, because JavaScript provides a for loop construct, but forEach provides one particularly important feature that often escapes even many senior-level JavaScript programmers: block level scope. To illustrate, first consider the following two approaches to iterating over an Array:

// Approach 1:
var arr = getSomeArray();
for (var i in arr) {
  /* manipulate arr[i] */
}

/* The last value of i is available here because the
   for loop does not have its own block level scope.
   Ditto for any temporary variables
   defined between the braces. */

// Approach 2:
var arr = getSomeArray();
dojo.forEach(arr, function(item) {
  /* manipulate item */
});

/* Neither item nor any temporary variables are
   available here because the scope of the anonymous
   function protected this outer scope from it. */

Styling Nodes

Another function you’ll use quite often for DOM manipulation is dojo.style, which acts as a setter when you pass it a node and a map of style properties as parameters and a getter when you pass it a node and a particular style property. In addition to providing an intuitive one-stop shop for style, it protects you from a number of DOM-based browser-specific quirks that otherwise would creep up on you. Here’s how it works:

// Set some style properties..
var fooNode = dojo.byId("foo");
dojo.style(fooNode, {
    color : "red",
    background : "white",
    border : "blue"
});

/* ... Lots of interesting things
       happen in the meanwhile ... */

// Get a style property such as width...
var props = dojo.style(fooNode, "width");

On a related tangent, you can use any combination of the dojo.hasClass, dojo.addClass and dojo.removeClass functions to inspect and manipulate classes in the same intuitive manner:

var fooNode = dojo.byld("foo");
if dojo.hasClass(fooNode) {
  // do something...
  dojo.addClass(fooNode, "bar");
} else {
  //do something else...
  dojo.removeClass(fooNode, "baz");
}

Querying The DOM

The dojo.query function provides a natural segue into general-purpose DOM manipulation and is based on CSS3 selectors. For example, you might use the following logic to query the DOM for any anchor tags and temporarily highlight the background to be yellow for a mouse-over event:

dojo.query("a")
.onmouseover(function(evt) {
  dojo.style(evt.target, {background : "yellow"});
})
.onmouseout(function(evt) {
  dojo.style(evt.target, {background : ""});
});

The statement inside the dojo.addOnLoad block queries the DOM for any anchor tags using the “a” CSS3 selector and returns a collection of nodes as a specialized subclass of Array called dojo.NodeList. Each of the dojo.NodeList methods is then successively applied to the collection of nodes with the final result being returned so that it can be captured into a variable if desired. The dojo.NodeList class provides a number of useful methods, such as addClass, removeClass, style and the various Array functions that you already have seen. For example, if you are seduced by the elegant dot notation that dojo.NodeList provides, you may find yourself with an expression like the following:

// find anchors that are direct descendants of divs
var highlyManipulatedNodes = dojo.query("div > a")
.addClass("foo")
.removeClass("bar")
.onmouseover(function(evt) { /* ... you ... */})
.map(function(item) { /* ... get ... */})
.filter(function(item) { /* ... the ... */})
.forEach(function(item) { /* ... idea ... */});

It is especially noteworthy that the dojo.NodeList methods named after and triggered by DOM events, such as onmouseover or onblur, accept a single parameter that is a W3C standardized event object, so you are freed from the development and maintenance of yet another layer of subtle incompatibilities when developing a Web application. In fact, the next section investigates the very mechanism that makes this possible.

Event Chaining

It’s quite often the case that you’ll need to chain together some events arbitrarily to produce an action/reaction effect. The dojo.connect function provides a seamless interface for arbitrarily connecting events and JavaScript Objects. For example, you already know that you could hook up a handler when a user mouses over a specific node by using dojo.query and assigning a function via dojo.NodeList’s onmouseover method like so:

dojo.query("#foo") //find the node with id=foo
.onmouseover(function(evt) { /* ... */ });

An alternative implementation via dojo.connect is the following statement, which assembles the connection and returns a handle that can be disconnected later manually if the situation calls for the relationship to be torn down. For example, it’s generally a good idea to tear down the handle explicitly before destroying nodes that are involved in the connection:

var h = dojo.connect(dojo.byId("foo"), "onmouseover", function(evt) {
  /* ... use the normalized event object, evt, here ... */
});

/* Later */
dojo.disconnect(h); //tidy up things...

Although the net effect is the same for the two implementations presented, dojo.connect seamlessly allows you to provide Objects as the context. For example, the following variation illustrates how to fire off an event handler whenever a particular function is invoked:

var obj = { // a big hash of functions...
  foo : function() { /* ... */ },
  bar : function() { /* ... */ }
}

// set the handler to fire whenever obj.foo() is run
dojo.connect(obj, "foo", function() {
  /* ... a custom event handler ... */
});

obj.foo(); // the custom handler fires automatically

If you want to use a particular scope with the custom handler, you can wedge it in as a third parameter. The parameters are all normalized internally. Here’s how it would work:

var obj1 = { // a big hash of functions...
  foo : function() { /* ... */ },
  bar : function() { /* ... */ }
}

var obj2 = { // a big hash of functions...
  baz : function() { /* ... */ }
}

// fire the handler whenever obj1.foo() is run
dojo.connect(obj1, "foo", obj2, "baz");

obj1.foo(); // fire obj2.baz right after obj1.foo

Pub/Sub Communication

Although dojo.connect provides a kind of direct action/reaction style of communication, the publish/subscribe metaphor has many highly applicable use cases in loosely coupled architectures in which it’s not prudent for objects or widgets to know about one another’s existence. This metaphor is simple enough to set up. The dojo.publish function accepts a topic name and an optional Array of parameters that should be passed to any subscribers. Becoming a subscriber to a topic is done through the dojo.subscribe function, which accepts a topic name and a function that is executed in response to the published topic. Here’s a working example with a couple Function Objects:

function Foo(topic) {
  this.greet = function() {
    console.log("Hi, I'm Foo");

    /* Foo directly publishes information,
       but not to anywhere specific... */
    dojo.publish("/lj/salutation");
  }

}

function Bar(topic) {
  this.greet = function() { console.log("Hi, I'm Bar"); }

  / * Bar directly subscribes to information,
      but not from anywhere specific */
  dojo.subscribe("/lj/salutation", this, "greet");
}

var foo = new Foo();
var bar = new Bar();

foo.greet(); //Hi, I'm Foo...Hi, I'm Bar

A couple variations on the pub/sub metaphor are available, but the vanilla dojo.publish/dojo.subscribe functions relay the general idea. Any situation in which you cannot (for whatever reason) expose an API might be a prime opportunity to take advantage of pub/sub communication in your application.

Object-Oriented JavaScript

JavaScript is an object-oriented programming language, but unlike the class-based languages of Java or C++, it uses prototypal inheritance as its mechanism of choice instead of a class-based paradigm. Consequently, mixing properties into object instances as part of a “has-a” relationship is often a far more natural pattern than attempting to mimic class-based patterns that espouse an “is-a” relationship. Consider the following example that adds in a collection of properties to an object instance all at once using dojo.mixin:

var obj = {prop1 : "foo"}

/* obj gets passed around and lots of
   interesting things happen to it */

// now, we need to add in a batch of properties...
dojo.mixin(obj, {
  prop2 : "bar",
  prop3 : "baz",
  prop4 : someOtherObject
});

The dojo.extend function works much like dojo.mixin except that it manipulates a constructor function’s prototype instead of the specific object instances.

Of course, there are some design patterns that do lend themselves to inheritance hierarchies, and the dojo.declare function is your ticket to mimicking class-based inheritance if you find yourself in a predicament that calls for it. You pass it the fully qualified name of the “class” you’d like to create, any ancestors that it should inherit from, and a hash of any additional properties. The dojo.declare function provides a built-in construction function that gets run, so any parameters that are passed in can be handled as needed. Here’s a short example demonstrating a Baz class that multiply inherits from both a Foo and a Bar class:

//create an lj.Foo that doesn't have any ancestors
dojo.declare("lj.Foo", null,
{
  /* custom properties go here */
  _name : null,
  constructor : function(name) {
    this._name = name;
  },
  talk : function() {alert("I'm "+this._name);},
  customFooMethod : function() { /* ... */ }
});

//create an lj.Bar that doesn't have any ancestors
dojo.declare("lj.Bar", null,
{
  /* custom properties go here */
  _name : null,
  constructor : function(name) {
    this._name = name;
  },
  talk : function() {alert("I'm "+this._name);},
  customBarMethod : function() { /* ... */ }
});

//create an lj.Baz that multiply inherits
dojo.declare("lj.Baz", [lj.Foo, lj.Bar],
{
  /* custom properties go here */
  _name : null,
  constructor : function(name) {
    this._name = name;
  },
  talk : function() {alert("I'm "+this._name);},
  customBazMethod : function() { /* ... */ }
});

//parameters get passed into the special constructor function
bartyBaz = new lj.Baz("barty");

When each of the dojo.declare statements is encountered, internal processing leaves a function in memory that can be readily used to instantiate a specific object instance with the new operator–just like plain-old JavaScript works. In fact, the bartyBaz object is one such instantiation. It inherits the customFooMethod and customBarMethod from ancestors, but provides its own talk method. In the event that it had not provided its own talk method, the last one that was mixed in from the ancestors would have prevailed. In this particular case, the ancestors were [lj.Foo, lj.Bar], so the last mixed in ancestor would have been lj.Bar. If defined, all classes created with dojo.declare have their parameters passed a special constructor function that can be used for initialization or preprocessing.

Note

Strictly speaking, there aren’t classes in JavaScript–only objects exist. When discussing simulated inheritance situations, however, it is not uncommon to use the word “class” as though classes really do exist, provided appropriate caveats (like this one) are applied.

Server Communication

No discussion of a JavaScript toolkit would be complete without a mention of the AJAX and server-side communication facilities that are available. Dojo’s support for server-side communication via the XMLHttpRequest (XHR) object is quite rich, and the dojo.xhrGet function is the most logical starting point, because it is the most commonly used variant. As you might have suspected, it performs a GET request to the server. Unless you configure it otherwise, the request is asynchronous and the return type is interpreted as text. Here’s an example of typical usage:

dojo.xhrGet({
  url : "/foo", //returns {"foo" : "bar"}
  handleAs : "json", // interpret the response as JSON vs text
  load : function(response, ioArgs) {
    /* success! treat response.foo just like a
       normal JavaScript object */
    return response;
  },
  error : function(response, ioArgs) {
    /* be prepared to handle any errors that occur here */
    return response;
  }
});

A point wasn’t made of it, but the reason that both the load and error function returns the response type is because Dojo’s I/O subsystem uses an abstraction called a Deferred to streamline network operations. The Deferred implementation was adapted from MochiKit’s implementation (which was, in turn, inspired from Python’s Twisted networking engine). The overarching concept behind a Deferred is that it provides a uniform interface that drastically simplifies I/O by allowing you to handle asynchronous and synchronous requests the very same way. In other words, you can chain callbacks and errbacks arbitrarily onto a Deferred, regardless of whether the network I/O is in flight, threw an Error or completed successfully. Regardless, the callback or errback is handled the same way. In some situations, Deferreds almost create the illusion that you have something like a thread at your disposal.

Here’s an updated example of the previous dojo.xhrGet function call that showcases the dojo.Deferred object that is returned:

var d = dojo.xhrGet({
  url : "/foo", //returns {"foo" : "bar"}
  handleAs : "json", // interpret the response as JSON instead

  load : function(response, ioArgs) {
    /* success! treat response.foo just
       like a normal JavaScript object */
    return response; // pass into next callback
  },
  error : function(response, ioArgs) {
    /* be prepared to handle any errors that occur here */
    return response; //pass into next errback
  }
});

/* The xhrGet function just fired. We have no idea if/when
   it will complete in this case since it's asynchronous.
    The value of d, the Deferred, right now is null since it
     was an asynchronous request */

//gets called once load completes
d.addCallback(function(response) {
  /* Just chained on a callback that
     fires after the load handler with the
     same response that load returned. */
     return response;
});

d.addCallback(function(response) {
  /* Just chained on another callback that
     fires after the one we just added */
      return response;
});

d.addErrback(function(response) {
  /* Just added an errback that
     fires after the default error handler */
     return response;
});

/* You get the idea... */

Again, the beauty of a Deferred is that you treat it as somewhat of a black box. It doesn’t matter if, when or how it finishes executing. It’s all the same to you as the application programmer.

Just so you’re aware, sending data to the server with another HTTP method, such as POST or PUT, entails using the very same kind of pattern and works just as predictably with the dojo.xhrPost function. You even can provide a form node so that an entire form is POSTed to the server in one fell swoop or pass in raw data for those times when you need to transfer some information to the server as part of a RESTful (Representational State Transfer-based) architecture. The dojo.toJson function may be especially helpful in serializing JavaScript objects into a properly escaped JSON string, if the protocol is something along the lines of a JSON-RPC system in which the envelope is expected to be JSON in both directions.

Special Effects

Simple animations are generally a crowd-pleaser, and Base includes a few easy-to-use functions that make animating content a snap. For starters, consider the dojo.fadeIn and dojo.fadeOut functions:

dojo.fadeOut({node : "foo"}).play();

// then sometime later...
dojo.fadeIn({node : "foo"}).play();

Hopefully, that seemed as simple as it should be: point to a node and fade it. It won’t be long though before you’ll find the desire to do some animations that involve arbitrary CSS properties, and that’s when the dojo.animateProperty function comes into play. The basic pattern is that you pass it a node, a map of properties and a duration, and it handles the rest. Here’s a simple example that relates the pattern via the dojo.anim function by providing functions for imploding and exploding a node:

//implode a node...
dojo.anim("foo", properties : {width : 0, height : 0}, 500);
//implode over 500ms

/* ... Later ... */

//then explode it back out
dojo.anim("foo", properties : {width : 300, height : 300}, 500);
//explode back out over 500ms...

A number of other useful animation functions exist in the dojo.fx module.

Highlights From Core

Although there is a ton of functionality jam-packed into Base, there are a number of other highly useful modules that you can get from Core at the expense of a dojo.require statement, which acts like #include from C++ or an import statement from Python or Java. Before providing an overview of what’s available in Core, however, it’s worth briefly summarizing how the dojo.require statement works, because it is a staple in the toolkit.

Requiring Resources

In Dojo parlance, a dojo.require statement generally fetches an entire module or a resource that is part of a module, and a module is just a JavaScript file arranged according to a particular convention. For example, if you were to download a source distribution of Dojo and browse the contents of the dojo/io folder, you’d see that an iframe.js file and a script.js file are present. The first statement in each of these files is dojo.provide(“dojo.io.iframe”) and dojo.provide(“dojo.io.script”), respectively. In this case, you’d say that the dojo.io module provides the iframe and script resources. The basic trade-off when designing modules is the balance between minimizing HTTP requests that incur a lot of latency and not downloading more content than you actually need. (The build tools included in Util, however, can consolidate multiple resource files into a single minified JavaScript file that nearly obliterates any concern surrounding this particular issue for many cases.)

Let’s put dojo.require to work by having it retrieve the dojo.io.script resource that we’ll use to fetch some public data using Flickr’s JSON with padding (JSONP) API. Like almost everything else in the toolkit, the dojo.io.script.get function that we’ll use abstracts most of the dirty work away, so you don’t have to write or maintain any of that brittle boilerplate:

//Require what you need...
dojo.require("dojo.io.script");

//...but don't reference it outside of the dojo.addOnLoad
//block or you'll create a race condition since dojo.require
//statements are satisfied asynchronously over the CDN...
dojo.addOnLoad(function() {
  dojo.io.script.get({
     callbackParamName : "jsoncallback", //provided by Flickr
     url: "http://www.flickr.com/services/feeds/photos_public.gne",
     load : function(response, ioArgs) {
      /* response is a JSON object with data about public photos */
      return response;
    },
    error : function(response, ioArgs) {
      /* ... handle the error ... */
      return response;
    }
  });

}

More Core

Although there’s not time to gloss over Core systematically the same way we did with Base, it’s well worth the time to explore it, and you’re now equipped with enough fundamental knowledge to go do some digging on your own. A few of the resources you’ll find in Core include:

  • Internationalization facilities and functions for computing dates,times and formatting currency.
  • Additional animation capabilities.
  • The IFRAME transport (useful for uploading files to the server).
  • Functions for handling cookies.
  • Powerful data APIs that abstract cumbersome server-side I/O.
  • Drag-and-drop machinery.

More Toolkit

And even though Base and Core are two substantial components of the toolkit, there’s also Dijit, DojoX and Util, which easily could span entire articles and books of their own. In short, Dijit is a huge infrastructure of DHTML-based turn-key widgets. DojoX is a collection of specialized subprojects ranging from wrappers around Google Gears to graphics functions that can use scalable vector graphics (SVG) to draw in the browser natively. Util provides DOH, a unit-testing framework and a collection of build tools for squeezing as much performance as possible out of your JavaScript. Although not covered in this article, these topics are well worth investigating and are just as important to your development efforts as Base and Core.

Resources

The Dojo Toolkit: dojotoolkit.org

The Official Dojo API: redesign.dojotoolkit.org

Firebug: getfirebug.com

Mozilla’s Developer Documentation on Arrays:
developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array

CSS3 Selectors: www.w3.org/TR/css3-selectors/#selectors

W3C Documentation on DOM Events: www.w3.org/TR/DOM-Level-2-Events/events.html

Python’s Twisted Matrix: twistedmatrix.com

MochiKit Deferreds: www.mochikit.com/doc/html/MochiKit/Async.html#fn-deferred

REST: en.wikipedia.org/wiki/Representational_State_Transfer

JSON-RPC: json-rpc.org

JSONP: ajaxian.com/archives/jsonp-json-with-padding

Flickr API: www.flickr.com/services/api

Clean Licensing: Why You Should Care (If You Don’t Already):
alex.dojotoolkit.org/?p=654

Dojo: The Definitive Guide by Matthew Russell:
www.amazon.com/Dojo-Definitive-Guide-Matthew-Russell/dp/0596516487

Matthew Russell is a computer scientist and technologist whose latest pastime entailed authoring Dojo: The Definitive Guide. With what little time is left over from writing, hacking on Web technology and noodling on hard computer science problems, he enjoys getting as far away from technology as possible by escaping for long bike rides near his home in Franklin, Tennessee.
September 9th, 2008 Comments Off
Tags: , , ,

Category: News

Dojo: The Definitive Guide – Now Available Through Google Books (and Fine Torrent Sites Everywhere)

A colleague just pointed out that select portions of my book are now available through Google Books, so you can now read a fairly substantial portion of it online — for free. Sure, I’d like to actually sell as many copies as possible, but the way I see it, the more I can help Dojo and the Open Web, the better the market economics work out in the end — probably.

On a related note, someone also pointed out not too long ago that the book is also available on several well-trafficked torrent sites — no links to those though; I’m sure you’ll have no trouble successfully stealing the book if you want it that bad.

So why even point that out? Well, a couple of reasons: 1) it’s not like I can stop you if you want to pirate the book, so pretending like it’s not out there isn’t going to change anything, 2) if there’s a secondary market for pirated versions of a printed book on technology, then that’s all the more reason to be excited about the success of the technology in general, and 3) if you do pirate it and like it enough, maybe you’ll actually buy it (not that I’m encouraging you to pirate it in the first place, though)

As the author of a book that’s being pirated, I guess it’s mildly flattering and mildly frustrating all at the same time. So before I forget: pretty please, with a cherry on top — don’t steal the book. You can read a lot of it online for free now, and if that’s not good enough, pick up a used copy on Amazon for cheap.