Dojo's Industrial-Strength Grid Widget

Dojo's grid widget provides a fierce alternative to the paginated table that has become such a mainstay of modern-day Web application interfaces.

In almost any application that's complex enough to require a database
for persistent storage, there is a need to render data in a tabular
format for display or interaction. Although a seemingly simple task,
it quickly becomes quite involved once you introduce the need to sort
columns, reorder columns, account for editing the contents of cells
and managing pagination. As you might expect, this is one of those
problems that has been solved so many times that commoditized solutions,
such as Dojo's grid widget, now are available for use. After all, you'd
much rather concentrate on actually building out the interesting parts
of your app than creating and maintaining the infrastructure that holds
it all together, right?

If you've been following along with my previous LJ
articles on Dojo (see Resources),
you should have a good idea of how to get Dojo up and running with
minimal hassle using AOL's Content Delivery Network (or if you
prefer, get it from the official Dojo Web site). As a reminder,
the minimal page template is basically an HTML page with a script tag
and a dojo.addOnLoad block that waits until all cross-domain loading
has completed before it executes in order to guarantee that dependencies
inside the code block have been met before it executes. You may recall
that the skeleton for this page looks something like this:

Prior to the Dojo 1.2 release, the grid was under heavy
development and largely in a state of flux. Although its API still
is subject to change, the 1.2 release substantially firmed it up, and
aside from accessibility considerations, it is expected to remain
intact. Bottom line: don't let the dojox namespace or previous experiences
with the grid prior to 1.2 scare you off; it's ready for prime time.
Although at the time of this writing, Dojo version 1.3 is just about to be
released, the code examples reference version 1.2 and work just
fine. There should be minimal, if any, changes necessary to update the
examples to version 1.3.

Now I'm going to move to putting the grid
widget to work, so consult a reference such as Dojo: The
Definitive Guide
(O'Reilly, June 2008) or on-line documentation at the Dojo Campus if you
need a quick refresher.

Dojo Data API Primer

The grid widget is necessarily data-centric and builds directly upon the
abstractions offered by the toolkit's robust data APIs, so a very brief
introduction is helpful for setting that context. In Dojo parlance,
the abstraction that the data APIs offer is a store that contains
items, where a store can implement a particular subset of the four
dojo.data APIs:

Read: APIs for querying items in a store.

Identify: APIs for uniquely identifying items in a store.

Write: APIs for creating, modifying and deleting items in a store.

Notification: APIs for triggering event handlers when items in a store are
created, modified or deleted.

The toolkit comes stocked with two handy store implementations that
are bundled into the dojo.data module: the ItemFileReadStore and the
ItemFileWriteStore. The ItemFileReadStore implements the Read and Identity
APIs, while the ItemFileWriteStore implements all four of these APIs.
Be aware, however, that the dojox.data module contains a plethora of additional
data modules for common tasks that you will want to leverage to your
advantage; interfacing with comma-separated value (CSV) files, Flickr,
Amazon's S3 service, OPML files and Atom content are just a few of the
handy implementations available (Figures 1 and 2).

Figure 1. Building on top of an abstraction such as the dojo.data
layer thins out the application logic and provides a uniform abstraction
for accessing data that is more maintainable and much less brittle.

Figure 2. Retrieving remote data from a server and massaging it into the
format expected by client-side JavaScript code has been a bane of Web
development for some time, and generally produces brittle designs that
do not sufficiently decouple the application logic from the underlying
data format being used.

In general, you provide data to an ItemFileReadStore or ItemFileWriteStore
in one of three ways:

By feeding it a file containing JSON data that meets a particular
structure.

By feeding it a JavaScript object conforming to the same structure as the
JSON file data.

By programmatically creating new items for the store.

Let's briefly consider examples that illustrate these operations. The
grid widget simply reflects whatever data is in the store that backs it,
so understanding how to manipulate data stores is essential to controlling
what ultimately appears in a grid widget (Listing 1).