Web developers are drawn to Dojo for its incredible collection of widgets, which can make even the most boring Web form come alive with surprisingly little effort. Dojo's out-of-the-box Dijit and Dojox controls are good enough to please all but the most discerning of users, but for those of you who refuse to fit your pages to conform to a pre-defined widget design, the Dojo Framework can also be extended to write your own widgets. It's a fairly painless way to combine several controls to enhance your business processes.
As with all Dojo widgets, you have the option of creating yours declaratively or programmatically. In today's article, we'll be taking the declarative route. Our widget will display financial information on some common commodities such as gold and crude oil. It will include a small graph as well as a list of details relating to that commodity.
Directory Structure for Widget Components
Under your Web server's root directory, you'll need to create some
folders to store the widget components. Most developers prefer to put their
custom widgets in a folder that is not under the
Dojo root because that can
be updated as new versions of the Dojo library are released. The standard place
for them is in a sibling directory called, you guessed it, "
widgetsfolder, you should have three or even four more subdirectories, depending on how modularized you want the various components to be. The subfolders, which very much mimic the usual Web server structure, include
templates. The page that will contain the widget(s) is called
stockWidget.htmland it resides in the root directory:
Note that I have left the widget script in the
for the purposes of development.
The Dojo Template File
Dojo Templates is one of the foremost reasons that Web developers
love the Dojo library, and it's easy to see why when you think about it. There
wouldn't be much point to building a reusable component if the HTML was buried
in the containing page, now would there? It makes sense to store the markup within
a template because it's really what represents an instance of your widget. Here
is what the markup for the
Widget Initialization Code
Although we are using the declarative style of widget creation,
we still need to include some code to initialize startup properties. Among the code
is the global
djConfig object. I prefer to declare it in code rather than as
a tag attribute because I find it easier to work with different data types that
HTML attributes don't support (they deal only with strings). For instance, the
modulePaths is an object literal that may contain paths for a number of modules.
In our project, we have two modules called templates and images. I always turn
isDebug flag in development, but then I remove it before rolling out
to production. The
parseOnLoad attribute tells Dojo to parse the HTML code for
controls to convert into widgets. In most cases, it's easier to let Dojo take
care of that job, even for custom widgets.
A second script appends the Dojo libraries. You can either use a hosted version of the script or serve it from your server, as I did.
The third and last script contains our widget code. The
method is an integral part of Dojo's module system and its loader. It tells
the loader that a module has been provided for the given name. It also creates
little later. We also need to import the
Here is all the code that we've discussed thus far:
dojo.declare() method provides functionality that simulates
Java's class system. It emulates OO constructs such as prototypal inheritance,
classical inheritance, and private members.
It accepts up to three arguments:
className (null|String): The optional name of the class to declare -- The
classNamewill be used as a global name for a created constructor. When specified, the name is stored in the created prototype's
declaredClassproperty. If you don't specify it, the class is assumed to be anonymous.
superclass (null|Object|Object):This parameter can be null for no base class, an object for one base class, or an array of objects for multiple inheritance.
props (Object): An object whose properties are copied (mixed in) to the created prototype after all other inheritance has been solved -- You can add an instance-initialization function by making it a property named
The following code declares the StockInfo widget:
Class Member Properties
The template is specified in the widget attribute
and points to some HTML within a single root node, which may include special
attributes on the tags as well as possibly substitution variables. It can either
be specified as a literal string such as
or pulled in from a file using
dojo.cache(). In addition to making your code
more modular, it's also a lot less cumbersome to write HTML in a template file
dojo.cache() method accepts a string
argument that specifies the path to the file that contains the HTML using the
modulePath that we declared in the
djConfig variable. It will load
the contents of the file via a synchronous XMLHttpRequest (XHR) call. The second
argument contains any additional path information as well as the file name.
The remaining properties store information that will be displayed
in the widget. They include the name, ticker symbol, price, and price change.
There is also an
imagePath, but we don't need to specify it just yet: