This tutorial is for Dojo 1.7 and may be out of date.
Up to date tutorials are available.
Beyond Dojo's Core: Dijit and DojoX
One of the things that differentiates Dojo from many other JavaScript libraries is its scope. While you can simply use the functionality of Dojo base, DOM, Ajax, effects and other common functionality, the toolkit provides much, much more. In this tutorial, we'll go on a quick tour of the Dojo Toolkit, to introduce some of the other components that are shipped with each release.
Getting Started
Up to this point, you may have only been working with the base functionality of Dojo. You might have ventured off into other parts of the core of Dojo, which would be modules contained in the /dojo/
directory of the distribution and have modules IDs that start with dojo/*
. If you downloaded a SDK distribution of Dojo, or checked out a version from SVN, you would notice that dojo
isn't the only package:
It is unlikely you have gotten this far and not nosed around little in different parts of Dojo, but just in case, let's go over some of the basics again.
Packages and Modules
Prior to Dojo 1.7, even while modules were logically grouped into "packages", there wasn't that formal concept and similar functionality was grouped into different "namespaces". In JavaScript, this meant that everything was declared in the global scope and you would access it via a global variable (e.g. dojo.byId("someNode")
). With the adoption of AMD, the concept of a "package" formally entered the lexicon and while the global variables are still available for most modules in Dojo since 1.7, the preferred method is to "forget" about namespaces and instead utilize AMD and the packages.
A package in Dojo is strictly an AMD package, which requires it to include a package.json
in the root of the packages directory, which describes the package. There are three packages that are distributed with a Dojo source distribution: dojo
, dijit
and dojox
. The fourth directory in the source distribution is the util
directly and is strictly not a package and contains useful utilities to make it easier to manage a Dojo project.
Modules are then grouped together into packages. A module is a JavaScript file that can be loaded via the Dojo loader (or another AMD loader) into your application. These modules will generally start with a define()
function. Because of the expansive nature of Dojo, you will find many sub-directories within one of the three "root" packages. Sometimes we refer to these as "sub-packages", but strictly speaking they cannot stand on their own as an AMD package. A module's Module ID (MID) will map directly to the path that is occupies within the package. For example the module /dojo/fx.js
would have a MID of dojo/fx
. There will often be other resources included in the package directory, including tests, CSS, language resources and images.
Base vs. Core
Traditionally (in Dojo releases prior to 1.7), there had been a set of functionality that was automatically available by default when you loaded the dojo/dojo.js
file into your application. This functionality is referred to as "base" Dojo. As of Dojo 1.7, this functionality was broken out from dojo/dojo.js
and placed into individual modules in the dojo/_base
directory. If you are running your application in "legacy" mode (async: false
) then these modules will get automatically loaded when you load dojo/dojo.js
. If you are running in async mode (async: true
) then these modules will only be loaded if required in directly or if another module that is loaded depends on that module.
The rest of the modules in the dojo
package are referred to as the Core. If you have been reading some of the other tutorials, you may have used other parts of the Core, such as dojo/fx
in the animation tutorial.
Dojo Core provides a wide range of functionality, including feature detection, deferreds and promises, event handling, data store, DOM manipulation, queries, DOM effects, window lifecycle management, mouse, touch and keyboard events, drag and drop, dates and internationalization.
A Traditional Example
This example makes use of some of the more "traditional" ways you might use Dojo (and potentially other JavaScript libraries) to do a level of DOM querying and manipulation:
require([ "dojo/query", "dojo/_base/array", "dojo/dom-construct", "dojo/domReady!" ], function(query, array, domConst){ function topLinks(){ var headings = query('h2,h3'); array.forEach(headings, function(elm){ var topLink = domConst.create("a", { href: "#top", innerHTML: "^top" }); domConst.place(topLink, elm, "before"); }); } });
The snippet queries the DOM using a CSS selector to indicate that we want both <h2>
and <h3>
elements, and uses each as a reference node to insert a newly created <a>
element. There are dedicated tutorials for working with dojo/query
, DOM functions and array helpers available to find out more.
Dojo Core Example
A simple example using a core module would be to create a function that compares two dates and returns the difference:
require([ "dojo/date", "dojo/dom", "dojo/domReady!" ], require(date, dom){ function daysSince(fromDate, target){ if(!(fromDate instanceof Date)){ fromDate = new Date(fromDate); } console.log("from date: ", fromDate); var now = new Date(); console.log("From Date: " + fromDate.toUTCString()); console.log("Difference in days: " + date.difference(fromDate, now, "day")); var days = date.difference(fromDate, now, "day"); dom.byId(target).innerHTML = days; } });
There is a wealth of functionality in Dojo Base and Core for common web and general-purpose programming tasks. These tutorials aim to introduce you to some of it, but it should not replace the broader familiarity you'll get from browsing the Reference Guide and the API Reference.
Dijit: Forms, Layout and UI Goodness
The dijit
package is a sibling to Dojo Core. It is managed and run as a sub-project of the Dojo Toolkit, with its own owner, policies and guidelines. Dijit is designed to be a set of visual elements that are "enterprise grade" and offer stability, accessibility and internationalization (including right-to-left and left-to-right support where applicable). It enhances native HTML controls like form fields, provides advanced layout capabilities as well as other common UI element interfaces. As well as being a set of visual UI elements, it is also a framework for defining custom widgets.
Dijit provides a series of controls which enhances basic HTML form controls with usability improvements, formatting and validation, as well as data-binding using the dojo/store API
See the Dijit Themes, Buttons, and Textboxes tutorial for additional reading.
View DemoDijit also has powerful tools for creating dynamic user interfaces that adapt to viewport size, and respond to resize and user interaction. It includes widgets for creating desktop-like application layouts and standard items like Tab and Accordion controls for making the best use of the space available.
View Demo
You don't have to use Dijit when you are building interactivity, but the controls and patterns it comprises have grown out of a combined and cumulative experience of many years of building web applications, making it a great base to build on and with.
See the Layout with Dijit tutorial for additional reading.
DojoX: Dojo Extensions
The dojox
package is a collection of sub-packages that extend the toolkit into common and less common areas. Each sub-package is a directory under dojox/
, and provides its own README
file which outlines the functionality and status of the project. Some code is stable and production-ready, while others are not. Here are some highlights in DojoX:
DojoX: Data Grid
One of the most widely used aspects of DojoX (let alone Dojo as a whole) is the dojox/grid
.
A highly flexible and feature-rich Dijit-based data grid control
See the Introduction to the DataGrid tutorial for additional reading.
One of the challenges though has been that DojoX DataGrid hasn't been up to the task of a more modern world, in particular the mobile browser world. While there had been some effort to enhance the DataGrid, ultimately it needed a fundamental rewrite. The Dojo Community has created two new grids that are re-writes from the ground up of the DojoX Grid. They are:
- dgrid - Created and maintained by SitePen, it offers a next-generation grid component that is designed for modern browsers and the Dojo Store API.
- GridX - A fast rendering, modularized and plugin architected grid component.
If you are starting new development, you should really consider adopting one of the newer grids, as they are going to be more likely to take advantage of modern browsers and mobile computing needs in the future.
DojoX: GFX
A cross-platform vector graphics API
See the Vector Graphics with Dojo's GFX tutorial for additional reading.
DojoX: Charting
Native charting built on dojox/gfx, with a broad selection of chart types, themes and features for visualizing data.
View DemoSee the Dojo Charting tutorial for additional reading.
DojoX: Mobile
A lightweight, cross platform, mobile widgets and application framework for mobile devices.
See the Getting Started with dojox/mobile tutorial for additional reading.
And the less photogenic, but highly useful:
- dojox/lang/functional
- A library of functional programming utilities which complement the array methods in Dojo Base to make your code expressive, compact and side-effect free.
- dojox/widget | dojox/layout | dojox/form
- Further controls to augment the selection provided by Dijit.
DojoX is a treasure trove of solutions for a wide range of problems, and many a rainy afternoon can be spent poking through its projects. You are encouraged to do just that - to spare yourself the forehead-slapping we've all experienced upon discovering in DojoX the very thing we've just spent a week working on.
For an overview of everything contained in DojoX, the DojoX Reference Guide is a good place to start.
Util
The util/
directory contains scripts and resources for packaging, testing and documenting your project. Util is not a Dojo namespace, and the contents are typically used outside the browser and your page. There is no "right" way to create and deploy web applications, but Dojo tries to provide tooling to facilitate some of the important best practices that have emerged over the years.
Each of the utils is documented in its own right, but we'll give them a brief introduction here:
Dojo Build System
Dojo's package system allows the code in the toolkit to be modular, with the filesystem layout following the module structure. This means that for even a simple application, your browser would be issuing dozens of HTTP requests for the individual modules. This is an acceptable trade-off for developer convenience, but for production, you should always use the build tools to combine these individual module files down to one or more "layers".
The build system is a JavaScript application, which runs on Rhino or NodeJS. Read more about the build system itself, and how to use it on your own code.
D.O.H.
D.O.H. is the test harness used by Dojo for its own unit tests. It includes an in-browser test runner and a non-browser, Rhino-driven test runner. DOH supports a simple set of assertions, and strong support for asynchronous tests, including a specialized implementation of Deferreds, meaning it can be used to test non-Dojo JavaScript as well.
For UI testing there is the DOH Robot, which is a Java applet-based web driver that can record and replay interactions with your pages. You can then take the recorded script and insert assertions as appropriate, making for a more complete test.
Extended Family
There is an extensive ecosystem of developers and resources working with and on the Dojo Toolkit. Many of them make available their complimentary code and related projects. Most of these additional libraries are located at the Dojo Foundation Package Repository and are easily installable via the CommonJS Package Manager.
Conclusion
The Dojo Toolkit is much more than a DOM and Ajax library. While it has feature and API overlaps with other libraries in this space, it is broader in its scope, and digs deeper in many areas to provide useful abstractions, widgets, and tools to help tackle the large and small, simple and complex, common and uncommon.
You won't learn it all at once - or perhaps ever - but as your requirements grow, Dojo grows with you.