Dojo: the JavaScript Toolkit with Industrial-Strength Mojo

 in
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.
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");
}

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Shaguf

Anonymous's picture

Hey Guys,
Author of More Servlets and JSP, Marty Hall is coming to Bangalore this April to speak on Choosing an Ajax/JavaScript Toolkit: A Comparison of the Most Popular JavaScript Libraries, Pure Java Ajax: An Overview of GWT 2.0, Integrated Ajax Support in JSF 2.0 and Ajax Support in the Prototype JavaScript Library. You can get more information on developersummit dot com

Geek Guide
The DevOps Toolbox

Tools and Technologies for Scale and Reliability
by Linux Journal Editor Bill Childers

Get your free copy today

Sponsored by IBM

Webcast
8 Signs You're Beyond Cron

Scheduling Crontabs With an Enterprise Scheduler
On Demand
Moderated by Linux Journal Contributor Mike Diehl

Sign up now

Sponsored by Skybot