Dojo HTML5 Data-Attribute Support

Dojo has long provided support for declaring widgets and specifying other information directly in HTML. This support makes it extremely quick and easy to get an application started. You can start instantiating widgets by adding attributes to HTML elements before even writing any code. This is not only a very convenient tool, but using a declarative approach to binding widgets to elements can be viewed as cleaner and more organized than using the imperative mechanics of JavaScript.HTML5 Powered with Semantics Widgets declared in markup have an encapsulated construction, avoiding instantiation that requires spanning and synchronizing HTML and code manually.

However, the use of Dojo's declarative tools has been avoided by many because it uses custom attributes that are outside the HTML specification and therefore do not validate against HTML validators. But now the new HTML5 specification provides a new namespace for custom attributes. The data-* attributes are available for libraries and authors to use for their own purposes and extensions while still having validating markup. The HTML5 specification further recommends that library use a sub-namespace for their custom attributes to avoid conflicts with other code. All of the Dojo custom attributes begin with data-dojo-. Let's let look at the new Dojo attributes.

data-dojo-config

The data-dojo-config attribute replaces the djConfig attribute on the dojo.js script element to allow for declaration of Dojo's configuration properties. Here we can specify settings like parseOnLoad, and isDebug. For example, we can load dojo.js with configuration information:

<script src="dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>

data-dojo-* for widgets

The new data-dojo-type attribute replaces the dojoType attribute to specify the widget class to instantiate a target element. We can add the data-dojo-type to an HTML tag and the Dojo parser will create a widget on that element. This works in conjunction with the new data-dojo-props which replaces the attribute-to-property mapping previously used by the Dojo parser. We can also use the new data-dojo-id to create a new globally rooted variable to reference the new widget. For example, to declare a widget:

<div data-dojo-type="dijit.Dialog" data-dojo-props='title:"My Dialog",
	onFocus:function(){ /* a focus event handler */ }'
	data-dojo-id="myDialog">
</div>

This will create a new dijit.Dialog widget, with the title property and onFocus handler set. It will make the widget available from the myDialog global variable. Remember to have parseOnLoad set to true or explicitly execute dojo.parser() after the page is loaded to ensure the widget gets instantiated.

Within widget templates, we can also use the new data-dojo-attach-event and data-dojo-attach-point as replacement for dojoAttachEvent and dojoAttachPoint to register attach points and attach event handlers. And finally, we can also use a data-dojo-event to define the event to register for <script type="dojo/method"> scripts.

When to go Declarative

Even when leveraging the new HTML5-valid custom attributes, there are still pros and cons to declaring widgets within HTML instead of with JavaScript. Declaring JavaScript components from within HTML introduces semantic impurity since the HTML is no longer is purely semantic markup, but includes tight coupling to particular visual components. The declarative approach also incurs extra CPU cycles because the dojo.parse() must traverse the DOM tree to find elements with Dojo custom attributes. Programmatic instantiation avoids unnecessary cycles and preserves semantic purity of HTML. However, markup-based widget declaration still has a powerful advantage by allowing us to define and create a widget in a single place, facilitating rapid application development with minimal effort.

Dojo still provides backward compatibility with the old custom attributes, but the new data-dojo-* attributes leverage the new HTML5 specification to provide fast and efficient declaration of widgets and configuration with clean and validating syntax.