Dojo 1.0: Client-Side Web Development Framework
Recently I started a deeper study of the Dojo JavaScript Toolkit 1.0. When I first got into Dojo, my reaction was something like "my goodness this is complicated", but then I woke up. In reality, Dojo is not simply a JavaScript framework like prototype or an animation framework like script.aculo.us, but, rather, it's an entire client-side web development framework. You can think of it as being a client-side version of the ASP.NET. Because of this, I'm not going to compare it to prototype or script.aculo.us, products, which have completely different applications than Dojo.
Here is a simple break down of an example based on the hello world example found on the Dojo web site. First let's add the dojo.js file:
<script src="dojoroot/dojo/dojo.js" djConfig="parseOnLoad: true" type="text/javascript"></script>
What in the WORLD is the djConfig attribute? Well it's not in any XHTML DTD that's for sure. This is something to tell Dojo to, obviously, parse the file on load. Duh. That's not really the fun part though. Check this out, you actually use a PHP style "require" statement to load specific portions of Dojo:
<script type="text/javascript"> dojo.require('dijit.form.Button'); </script>
By doing this, now we can add the following control into our page structure:
<button dojoType="dijit.form.Button" id="hola"> Hola Mundo! <script type="dojo/method" event="onClick">alert('Hola');</script> </button>
This creates a simple button which alerts 'Hola' when clicked. As you can see, it gives you a very nice declarative programming model. I personally think this is incredible because 1) I believe that we should focus on web development from a client-side perspective and therefore create controls on the client, 2) I love declarative programming, 3) I don't want to build this thing myself. With Dojo I get a declarative client-side programming model without having to architect the internals. This is really awesome, since I'm a strong advocate of client-side perspective programming (a.k.a. web 2.0).
One interesting aspect of Dojo is that it loads only the files that you need for that specific page. This is a rather nice compromise between the Prototype and mooTools methods. Prototype loads the entire thing into memory and mooTools allows you to download each section you want. Dojo, however, installs on the server as a set of files that are available for download and you retrieve them as you need them. To add to this, you don't add them via the <script /> element, you add the dojo.js file that way, but you load the others by calling dojo.require( ). What's nice about this is that you load modules, not files. It also gives it a more native programming feel, but it also makes sure you don't load the same file twice. Here's an example of what I'm talking about:
<script type="text/javascript"> dojo.require('dojo.parser'); dojo.require('dijit.form.Button'); dojo.require('dijit.form.FilteringSelect'); dojo.require('dijit.form.CheckBox'); </script>
Here you can see that I'm loading up four different modules. What's interesting about this is that it's kind of similar to how we import .NET namespaces. However, it's even more like how we load .NET assemblies. Think of each one of these as being an assembly we need to reference. In .NET, you add a reference, let fusion and it's buddies find and load the assemblies, and simply use the controls as if they were local; you don't care about "files". This is very similar to the model presented in Dojo. It's like you are adding a Dojo "assembly" reference, letting it load it for you, and you access it as it were local. This is all in direct contrast to the model that PHP as well as most JavaScript/AJAX framework use. In PHP and in these frameworks, you typically load "files" directly. One of the hardest things for a PHP developer to do is make the mental transition from file files to "magically loading" .NET assemblies. In .NET assembly names don't need to match their DLL names, in fact as assembly can span more than a single DLL file! In the same way, Dojo's module names don't have a one-to-one module-to-file mapping and loads whatever physical files you need based on the logical name you request. Very nice! The analogy isn't perfect and like I've already mentioned it's a bit like the .NET namespace import model as well.
Dojo contains a number of very nice controls as part of it's Dojo Widjet Library, also known as Dijit. Many of these are controls that most of us have wanted for years, but just have never had the time to mess with. For example, Dojo including a slider control, a dynamically expanding textarea, and a filtering select box. There's a whole host of others, but these are the ones that I personally have wanted to see in a professional framework for a long time. There's also a progress bar control and a dialog control for those of you who are into business apps. Dojo actually provides a tooltip dialog control as well. This control, as the name suggests, shows a dialog as a tooltip. The only time ever seen a control like this used was on the Facebook login screen, specifically when you check "Remember me". Another interesting thing related to controls is that Dojo gives you the ability to transform controls into a more beautified form. It's able to do this because it ships with a few CSS files that give Dojo its initial look and feel. Furthermore it also includes a number of themes. You can see this in a few of the more basic demonstrations in the Dojo documentation.
Dojo also includes many layout controls including a split container, accordion, tab control and what is called a StackContainer. This container shows a pane on the screen and gives you a next and previous button so you can go back and forth between panes. There's also a rich text editor control. That should get some people's attention right there. As cool as that is though, I don't think anything beats the grid control. The grid is like a combination of ASP.NET's GridView and WPF's Grid. It allows databinding like GridView, but it also allows complex row and column adjustment like the Grid. Technically it's not part of the core of Dojo, but it's incredibly amazing. You can see a great example of a Grid with it's code, see this example. The code for this Grid is so simple, that you probably won't even believe your eyes. Even still, the author of that example writes about the example here. The Grid really is one of the most powerful controls I've ever seen in a client or server technology. Again, can you see how Dojo is like a client-side ASP.NET?
It should go without saying at this point, but Dojo also includes various validation controls. You can actually put an <input /> element on the screen and set dojoType="dijit.form.DateTextBox" and you get an entirely new animal that loads a calendar control when you click in the textbox. If you prefer to type the date out by hand, the field will be validated automatically. You can also validate against money. Look at this example from the Dojo documentation:
<input type="text" name="income1" value="54775.53" dojoType="dijit.form.CurrencyTextBox" required="true" constraints="{fractional:true}" currency="USD" invalidMessage="Invalid amount. Include dollar sign, commas, and cents." />
That's seriously detailed. The data is validated as the user types. If you want to validate numbers that don't represent money, you can use the NumberTextBox Dojo control (also set via the dojoType attribute). Or, if you want more powerful validation, use a ValidationTextbox and set the regExp attribute and validate directly against a regular expression. Your regular expression doesn't have to be inline in the regExp attribute either. Take a look at this example from the Dojo documentation:
<input type="text" name="zip" value="00000" dojoType="dijit.form.ValidationTextBox" regExpGen="checkForFiveDigitZipCode" required="true" invalidMessage="Zip codes after 5, county name before then." />
Here you can see that the JavaScript function (checkForFiveDigitZipCode) is called for validation. To see these examples run and to see more information on validation in Dojo see the validation page in their documentation.
At this point I think I should mention something. As many of you know, I'm a strong standards advocate and an extremely outspoken opponent of the mere existence of Internet Explorer. Having said that, laws exist for a purpose and, frankly, only within the bounds of that purpose. The purpose of standards are to give us a common ground and to help us have cleaner, more professional work (my "having higher web standards" thing I'm always talking about). In terms of web browsers, each browser needs to continually keep up with the standards. Why? Obviously so web developers can ship out content and not want to change their career every single time they realize that browser X, Y, or Z doesn't support a specific feature. With this in mind, there is absolutely nothing wrong with Dojo using custom attributes on types. Dojo is requiring new functionality, but it's also providing that functionality at the same time. That which is requires, it provides. This is completely legal within the bounds of the purpose of standards. So, there is no reason for anyone to start crying about Dojo adding custom attributes. There was a time when I was a standards extremist (~2003), going so far as to even use a custom DTD on my pages where I would use custom attributes (set via JavaScript), but I've since realized that standard extremism is practically a cult and have ran from it. Also, and you may want to sit down for this one, I think that Dojo holds nicely to semantic web principles. Notice we aren't creating an input and procedurally making it do validation, rather, we are creating something that is a validation box. It's not as semantic as a <validationtextbox /> would be, if it were to exist, but as with most things, semanticism (huh?) is a continuum. If it weren't a continuum, <input type="hidden" /> shouldn't exist or ever be used (I would argue that this does in fact have some semantic value!) Because of this, I don't see Dojo involving itself with the evils of pragmatism. However, Dojo would be an evil pragmatic framework with little semantic structure, if it instead tried to setup some type of configuration system by setting class names. Can you even imagine the chaos? I've done this before as a standards extremist and it's really nasty.
Another thing that's insanely cool about Dojo is the event system. As we ASP.NET developers know, events aren't simply things you use on visual controls. No, you use events to notify entities of (...drum roll please...) events. So, you could have multiple entities monitoring a centralized entity, perhaps a service and when that centralized entity sends out an update, all the other entities immediately receive the update. It's the observer pattern, but you may know it as the publish/subscribe model. Normally when you think of JavaScript events you think of events in terms of visual control events just as you would with ASP.NET. With Dojo, however your event model gets an upgrade with a publisher/subscriber model. Here's an example for you to ponder:
<script type="text/javascript"> function Client (name) { this._name = name; dojo.subscribe('update', this, update); function update(args) { console.debug(this._name + ': ' + args); } } var Server = { sendUpdates: function(message) { dojo.publish('update', [message]); } }; var clientA = new Client('Client A'); var clientB = new Client('Client B'); Server.sendUpdates('event occured!'); </script>
One thing on which I would like to warn all my .NET colleagues is this: they use Java terminology. They fire their events whereas we like our events and think they are doing a great job so we raise them. Personally, I've never understood that terminology, especially in systems like the web that allow for event bubbling where events are RAISED to the top. OK, enough rant. Before moving on though, just think about what I keep mentioning : this is like a fully fledged client-side ASP.NET. You must surely be noticing that by now.
Dojo, of course, also gives you a XMLHttpRequest abstraction layer so that you don't need to mess with all that browser detection nonsense. The syntax is rather similar to prototype's very intuitive syntax. This is fortunate, because not all frameworks have a nice abstraction layer. I've given up on trying to figure out mooTool's abstraction layer a long time ago. It's doable, but the complexity curve is very steep. In Dojo, however, the complexity curve is relatively flat, like prototype's. Here's an example based on a Dojo documentation example of a simple XHR call (if you like, you can set 'json' instead of 'text' in the handleAs). This code isn't anything fancy, but that's kind of my point:
<script type="text/javascript"> dojo.xhrGet({ url: '/file/1.txt', handleAs: 'text', timeout: 3000, load: function(response, ioArgs) { alert(response); return response; }, error: function(response, ioArgs) { console.error('Status code: ', ioArgs.xhr.status); return response; } }); </script>
As simple as this is though, you can do much more with Dojo's abstraction layer than what I've seen in any other framework. For example, there's actually a dojo.io.iframe object to give you the ability to do iframe-based AJAX. Dojo also includes the dojo.rpc object, which allows for incredibly poweful RPC calls. Gone are the days of having to choose to either create your own end-to-end communication or to completely use a flawed product. You now have a nice middle ground for your AJAX service access. In a sense it's kind of similar to .NET remoting, in how it's not SOAP, but it's not quite sockets either. The dojo.rpc concept is amazing quite possibly my favorite Dojo feature. You can expect me to write more about this feature in the future. I'm been completely taken in by this incredible feature and can see an incredible number of applications for it. If you want to see something else wildly awesome, check out the dojo.data data access layer. The documentation needs to be developed a bit more, but it's wild. Whereas dojo.rpc may be similar to .NET remoting, dojo.data is kind of like WCF binding. You just connect to a built-in or custom data store and your can bind Dojo controls directly to it! Bind directly to your Flicker.com datastore or write your own. For a few good examples of using this feature, check out this blog entry.
There are also features which we would kind of expect from a client-side framework like drag-n-drop support, animation support (though barely documented-- here's a PDF of an example), and DOM node selection (see dojo.query). It also gives you control over internationalization (and unicode encoding) and the power to handle the back button in AJAX applications (of course by using the # syntax). There's also the ability to create object-oriented class with inheritance. One downside to this feature is that Dojo went back to the days of C++ and impossibly complex object graphing by allowing multiple inheritance. You may want to set a corporate guideline to stop people from doing this, lest your object graphs become completely unreadable. In any case, you also have an abstraction for arrays (to help emulate JavaScript 1.6), cookies, strings and dates. You are also provided a mechanism for converting the data of an entire form into JSON data.
As if that weren't enough, Dojo also provides a unit testing framework called D.O.H. You can do anything from simple asserts to full test cases, including grouping test cases. In addition to the unit testing, Dojo allows you to send informational and debug messages to the Firebug console. The documentation is packed with more testing samples than you will know what to do with. Most of them are for testing the Dojo framework, but these tests use D.O.H. and give you a world of insight into the variety of things you can do with Dojo.
As far as documentation, there is more documentation for Dojo than I have seen in all the other JavaScript/AJAX frameworks combined. The online "Book of Dojo" is incredibly long. In fact, some may say that it's too long. The Dojo people thought of this though and allow you to quickly get ROI from their "Dojo for the Attention-Impaired". This page demonstrates the basic idea behind Dojo by showing a quick Hello World example. I would recommend you do skim through this page, do the demo, then skim through the rest of the book, doing demos as you go. One thing I should mention about the documentation is that while there is a lot of it, it's very hard to read at times. I had to read the event system documentation numerous times before I was able to get anything from it. This is definitely something the Dojo guys should look into.
Another thing they should look into is their use of double quotes in their JavaScript documentation. This is something most ASP.NET AJAX books do and it really makes the code hard to read and hard to manage (do you really want to escape every single double quote in your HTML controls? ouch!) It's makes about as much sense as using double quotes in your T-SQL code (which, yeah, would require a setting, but that's my point-- it's lame). The Dojo documentation seems to go between various authors who either respect for the JavaScript guidelines (') or who don't even realize it exists ("). To make things worst, at times they use single quotes in their HTML! There doesn't seem to be any consistency here. I'm glad they didn't try to mix their code with any type of server-side work. I don't even want to try to read double-quotes JavaScript in the midst of PHP, Java, or C# code. That would e painful to read. Other than these two concerns, the documentation was fairly exhaustive. Some developers, however prefer to learn by seeing. If you're one of those, you can check out the official Dojo demos.
In terms of deployment, you actually don't even need to install Dojo. It's on the AOL Content Delivery Network (CDN), so you can quickly just include the Dojo entry file from their server and be done with it. If you really want to download it to your system, you can hit up the Dojo web site and download it from there. You could also head on over the the Dojo web site that parodies the script.aculo.us web site: dojo.moj.oe. Also, remember that everything you need is accessible from the single Dojo entry file (often dojo.js) and that you use dojo.require( ) statements to bring in functionality at a module level, not a file level. Therefore, the AOL CDN method should be perfect for most people.
Dojo is currently in version 1.0, however, this is an open source 1.0, not a Microsoft 1.0. When Microsoft has an alpha, it's a preview. When they have a beta 1, it's pretty nice. When they have a beta 2, I'm usually using it in production. When it's RTM as v1.0, everything breaks and I end up removing it. Google products as well as Firefox and Dojo on the other hand are hardcore and stable when they hit 1.0. Their idea of 1.0 is like Microsoft's idea of an SP2. Shall I remind everyone that Gmail is STILL marked as beta after all these years?? Dojo is a stable system that have been in development and testing for an extremely long time.
Dojo really is a fascinating client-side web development framework which can bring great elegance as well as a great declarative programming model to your AJAX applications. Furthermore, given it's rich set of controls, Dojo is absolutely perfect for web-based business applications. Dojo is also probably one of the great technologies of all time that are destined for completely misunderstanding as a product comparable and/or equal with products that don't even come close to it. There are people living today that still try to compare Internet Explorer with Firefox, VSS with Subversion, Gimp with Photoshop (oh yes, I went there!), the Zune (which is a media player) with the iPod Touch (which is an Internet device)and Gmail with Yahoo! Mail or Hotmail. Compare them and you will see there is no comparison. As I said at the beginning, this neither replaces prototype or script.aculo.us, which would be used in more minimal environments. Dojo is a different framework to be used when a project has different requirements. Besides, you should never choose one tool as your end all be all for everything. That's a naive way of thinking, unless you actually think it wise to cut your bread with a butter knife or spread your butter with a bread knife. Rarely are things in life one-side-fits-all. Frameworks are free; use them, but use them wisely. Hopefully many of you will seriously consider using Dojo in your current or future AJAX and ASP.NET projects.
Links
- Dojo on AOL CDN
- The Dojo ToolKit Download (you may not need to do this-- you can simply include the AOL CDN Dojo entry file)
- dojo.moj.oe (parody of script.aculo.us web site)
- Dojo Documentation
- Official Dojo Demos
- AdvancED DOM Scripting: Dynamic Web Design Techniques (the absolute deepest AJAX book ever written -- you will want this by your side when you work with Dojo or any other framework)