28 Days of Dojo

Today I am starting the “28 Days of Dojo” blogging marathon. So far I am the only participant but I welcome any and all to chime in or give me ideas. I am by far not a Dojo expert so, this month should be fun, I hope to learn a lot. I will be posting one blog entry related to Dojo every day in this month, starting with today, let’s see if I can do it.

So let’s get going, according to Merriam-Webster:

Dojo a school for training in various arts of self-defense (as judo or karate) link.

Unfortunately, that is not the Dojo I will be writing about. This is. If you are new to Dojo or have never heard of it you might want to start by reading the Dojo Foundation site. Dojo is backed by some of the biggest players in the software industry including IBM, Google, Sun (not so large any more), and Aptana. I have used Dojo on a few projects and most notably the Attachment Viewer on OpenNTF. I have also done a lot of jQuery on this blog and a couple of other sites so I have an appreciation for at least two of the best JavaScript frameworks out there. Dojo 2.0 has a lot of promises and it looks like it’s going to be an excellent upgrade.

The rest of these posts should be fairly technical and I might often compare approaches to jQuery.

The Dojo Toolkit

The Dojo Toolkit is the second place to start.

It is where you can download all of the code, reference all of the API’s and see some great examples for how to do this both declaratively and programmatically.

The documentation page has a nice layout where you can essentially pick a topic and find a sample, like “Fade in a node“. If you want to use Dojo in your project you can get the code and minimal JavaScript from the current-stable site or you can just use the Google content delivery network (CDN). Check out the Google developer page for how to get started.

Dojo.require() is your friend

One of the cool parts of Dojo is the ability to only load the modules and widgets your page needs. This is done with the dojo.require() method. Wherever your script is you can call dojo.require() and the module will be loaded in real time. The follow is an example of some script blocks that may be in the page header of an HTML page:

http://js/dojo.xd.js
 dojo.require("dojox.encoding.base64");
 dojo.require("dojo._base.xhr");
 dojo.require("dijit._base.manager");
 dojo.require("dijit.form.Button");
 dojo.require("dijit.Toolbar");
 dojo.require("dijit.Tooltip");
</script>

Dojo.require() does a lot of work for you. For instance it will not load the modules more than once and will load all dependent modules for you. One thing you will read in the help is the combination of using dojo.require() with dojo.addOnLoad(). This insures the module is loaded before you continue executing any relying code. So it is a best practice to chain these calls together when calling require() dynamically.

dojo.addOnLoad(function(){
  dojo.require("dijit.Dialog");
  dojo.require("dijit.TitlePane");
  dojo.addOnLoad(function(){
      // dijit.Dialog and friends are ready, create one from a node with id="bar"
      var dialog = new dijit.Dialog({ title:"Lazy Loaded" }, "bar");
  });
});
-link

The Dojo Toolbar dijit

One of the best things about using a JavaScript framework like Dojo is getting something up and running very quickly. The dijit.Toolbar is no exception. You can get a very quick toolbar by just using the declarative method right in  your HTML. If you are using the declarative method then you need to make sure you parse the DOM on load, this is how you tell Dojo to parse on load:

http://js/dojo.xd.js

To get some cool look and feel you should then include one of the base Dojo style-sheets in your code. The easiest way to do this is just make the entire <body> use the style sheet so all sub-elements will inherit it:

<body style="margin:0px; padding:0px;">

You will also have to define in your CSS the images you want to use for the buttons (if they are icon buttons). Make sure you specify a height and width!

.iconfilm {
   background-image:url(icons/filmstrip.png) !important;
   width: 22px;
   height: 22px;
}
.iconthumb {
   background-image:url(icons/thumbnail.png) !important;
   width: 22px;
   height: 22px;
}
.iconslides {
   background-image:url(icons/slides.png) !important;
   width: 22px;
   height: 22px;
}

Lastly, you just put the code directly in your HTML. Declaring the toolbar as the outer

and then each button individually. You could also include this inside of an XPage, JSP, or PHP file and conditionally show or not each button. Notice I use a and a connectId to attach a Dojo tooltip to each icon.

iconfilm" showLabel="false">
<span id="fs_tip" dojoType="dijit.Tooltip" connectId="toolbar1.filmstrip">Film Strip</span>
iconthumb" showLabel="false">
<span id="slides_tip" dojoType="dijit.Tooltip" connectId="toolbar1.slides">Slides</span>
iconslides" showLabel="false">
<span id="thumb_tip" dojoType="dijit.Tooltip" connectId="toolbar1.thumbnail">Thumbnail</span> </div </div>

This code was taken from the Attachment Viewer project on OpenNTF. You can download the project and see how the code works. Here is a screen shot of the toolbar in the Lotus Notes client:

Make sure you check out the awesome online documentation for the dijit.Toolbar!

As for a jQuery version of Toolbar, I couldn’t find one. I did find a really nice article that shows how to create a CSS based toolbar with some cool jQuery effects. Check that out and if you find an actual toolbar plugin for jQuery let me know.

Dojo and Ajax

If you want to create really compelling sites you have to master Ajax – shorthand for Asynchronous JavaScript and XML, link. There are also a few patterns you need to consider when implementing a “Web 2.0” like site. The most important can be described in this small code flow:

User Click -> show “loading” UI, getUI with Ajax -> On Complete -> Show new UI

The key is to chain together as many asynchronous events as possible to get a seamless flow in your code. Each JavaScript framework has a way to do this, and Dojo’s is dead simple.

There are three main methods used for this:

dojo.xhrGet

dojo.xhrPost

dojo.xhrPut

dojo.xhrDelete

The two most widely used are clearly xhrGet and xhrPost. They are pretty self explanatory in that an xhrGet allows a REST call to “get” data from the server and the xhrPost allows you to “put” data to the server. They both support a response and a key aspect of Dojo is you can tell the API what kind of response you expect using the handleAs parameter. The default is to handle as “text” but other formats like “xml” and “json” are also supported.

Since the API’s are very similar let’s focus on the post and then compare it to how it is done in jQuery.

Both Dojo and jQuery support the serialization of a form within the API but they each take a different stance on how to do that. Check out the sample code from the Dojo.xhrPost() reference:

            var xhrArgs = {
                form: dojo.byId("myform"),
                handleAs: "text",
                load: function(data) {
                    dojo.byId("response").innerHTML = "Form posted.";
                },
                error: function(error) {
                    //We'll 404 in the demo, but that's okay.  We don't have a 'postIt' service on the
                    //docs server.
                    dojo.byId("response").innerHTML = "Form posted.";
                }
            }
            //Call the asynchronous xhrPost
            dojo.byId("response").innerHTML = "Form being sent..."
            var deferred = dojo.xhrPost(xhrArgs);
        });

Notice the “form” parameter in red. The Dojo API allows you to just specify a DOM node for a form and does the serialization for you. If you do not want to post a form but some of your own data you can optionally use the postData parameter versus specifying a form. This is similar to jQuery.

The jQuery.post() is just as nice but you have to specify the data serialized:

$.post("test.php", $("#testform").serialize(),

   function(data){
     alert("Data Loaded: " + data);
   });

Don’t get scared with the “$” stuff, that is just short for “jquery.post()”. Notice you use the famous jQuery selector and just call serialize()? You could optionally massage the data and then serialize if needed. The callback for jQuery.post is actually the third parameter. If you want finer granularity with success or failure you might want to use the base method:

$.ajax({
  type: 'POST',
  url: url,
  data: data,
  success: success
  dataType: dataType
});

So what is the net of this? I choose Dojo over the jQuery implementation in this case. The reason? The “form” variable. By just specifying the DOM element of the form the Dojo code under the covers does the serialization for me – dead simple. If I want to get fancy I can also optionally override the call with postData to be more like the jQuery call. I have done a couple of jQuery sites and to be honest I end up using the $.ajax() base call over the $.post because I need to handle the various error conditions and also pass more context to the calling function. So while the nice function to encapsulate “get” and “put” in jQuery its really not that more useful then just calling $.ajax().

Connect with Dojo

Dojo.connect() is a very powerful function. It not only allows you to connect to various DOM and user events but it also lets you connect to other JavaScript methods and custom events. You can read about connecting to custom objects and functions in the online help here.

The most common use case for dojo.connect() is probably attaching to things like buttons or DIV clicking but you should consider using the Dojo event system for more than just user interface based events. It’s a good way to create a decoupled event system for disparate components.You can learn about creating such an event system by reading the documentation on dojo.connectPublisher(). It shows how you can publish events on a specific topic.

Many times you don’t even need the dojo.connect() for UI based events because you can do that inline using the regular JavaScript way, like this:

<img
    id="btn_pin"
    style="float: right;cursor: pointer;"
    title="Un-pin Attachment"
    src="icons/pinned-down.png"
    onClick="togglePin();">
</img>

But, let’s say each page has a specific button bar action or menu action like “New”. Each page could connect its own handler to that button based on the context. So you would leave the HTML onClick() attribute blank and use dojo.connect() to handle the click event for that page:

function conectToolbar(){
  dojo.connect(dojo.byId("btn_pin"),"onclick",createNewDocument);
}

The third parameter is simply a JavaScript method in the current context.

Now, how does this stand up to jQuery? Once, again, I think Dojo offers more flexibility in this space because it essentially supports a custom event model where the traditional jQuery approach uses bind.  jquery.bind() or more commonly, $.bind(), let’s you attach to all of the common DOM events for an element. So using the powerful selector API you can attach to any DOM related event (link):

$('#foo').bind('click', function() {
  alert('User clicked on "foo."');
});

This tells jQuery to bind to the element with the id of “foo” and attach to the “click” event.  In the above sample an inline function is used but you could have specified any JavaScript function in the current context. You can learn more about the different events supported in the help. jQuery does in fact support custom event types so you could simply generate your own event names and use the trigger() method to publish the event to any listeners. This basically allows you to achieve a generic pub sub without using additional plugins. This is described really well on another blog, check it out here. From what I can tell however, there is no built in way for jQuery to do this and the referenced article talks about the plugin Peter Higgins wrote for general pub/sub. What I really like about the article is how the author actually performed tests to see how fast the jQuery custom event method performs to the general pub/sub plugin. Check out his results, they clearly show using jQuery DOM events for custom events is way slower than using the pub/sub mechanism.

So what is next? I guess one thing would be to test this same level of performance testing using Dojo pub/sub versus the connect method. I checked the Dojo source and it looks like Dojo.connect does not use the Dojo.publish/subscribe libraries under the covers so it may result in the same poor performance results as jQuery. That might just be another blog post!

Another excellent article to read is the one on DeveloperWorks by Mike Wilcox – Conquer event-driven design using dojo.connect.

New search URL for Dojo posts

I have received a lot of positive feedback on this series so I decided to create a new link in my header “28 Days of Dojo”. The link does a tag search and sorts the results in ascending order. So if you want to read the series in order of entry you can. As the month goes I plan on making the posts more and more technical so reading in order is best for anyone just starting this stuff.

You can also bookmark the link here if you want to save it – link.

Special Effects and Dojo

If you want a slick looking site you need to master FX. There is no better way to have great FX then to use the different features in a JavaScript library like Dojo. We will start with the basic functions in the Effects area. Interestingly, both jQuery and Dojo do a good job in this space and are very similar in both API’s and supported behaviors.

If you are a CSS junky then you need to look at dojo.animate() and jquery.animate(). These methods can animate any CSS property, so the possibilities are infinite.

In Dojo, for the most control you can check out the dojo.anim() page for the different properties:

Parameter Type Description
node DOMNode|String Can be a DOM node or the id of a node (as string) to animate CSS properties on.
properties Object
duration Integer The number of milliseconds over which the animation should run. Defaults to the global animation default duration (350ms).
easing Function An easing function over which to calculate acceleration and deceleration of the animation through its duration. A default easing algorithm is provided, but you may plug in any you wish. A large selection of easing algorithms are available in dojo.fx.easing.
onEnd Function A function to be called when the animation finishes running.
delay Integer The number of milliseconds to delay beginning the animation by. The default is 0.

Mixing the duration, delay and easing properties gives you a high level of control for the animation behavior. You can also create some pretty cool effects by making DIV’s and other DOM elements have a full transparency level and then fade them in when needed. I have mixed using the Ajax techniques to go and get new DOM contents and slowly fade them in for instance. You can then override the onEnd method to provide your own function when the animation is complete. This is very useful when you need to create a full transition effect or chain animations together to create a seamless animation among multiple effects.

Over the past few versions it looks like most of the new stuff is being added to the dojo.fx package. Things like slideTo, wipeOut, wipeIn, and Toggler are all part of the FX package. These are more basic functions similar to what is provided in jQuery, which we will talk about next.

jQuery is almost identical in FX support – the methods and signatures are almost identical. You can look at the reference of $.animate(). I actually like the jQuery API a little better because you can provide a step function to change the animation during the animation. So for instance, you could have an animation that starts off fast then eases slowly to finish – very cool.

Lastly, you can also use the higher level calls for basic animation like dojo.fadeIn(), dojo.fadeOut(), or the jQuery equivalents: $.fadeIn(), $.fadeOut(). jQuery also has some other high level cool methods like $.fadeTo() and $.fadeToggle() that could come in handy.

In the end, I think jQuery excels in more higher level functions and for the most part people will probably use them versus trying to figure out all of the various ways animate() can be called. I have personally used $.hide() and $.show() a lot because they are just so simple to call and because they support the callback function it makes it very easy to chain effects together. If you want to check out all the high level effects support in jQuery check out the effects page. I really don’t like how Dojo has some functions in base dojo and others in dojo.fx, they should deprecate the dojo.XXX transition calls and just stick with dojo.fx for consistency.

Lotus bubble – Make Dojo better…get involved!

As a community, the Lotus community is very strong. We all get involved with things like OpenNTF, blogs, tweets, etc. One place I see Lotus fall short is getting involved with the many technologies our core Lotus products use – like OSGI, Eclipse, CKEditor, and Dojo.

Dojo is no exception! We, as a community, need to make this the best JavaScript library out there. So I urge everyone to start learning it, fixing it, documenting it, and promoting it. If you see a problem with an API or the documentation then fix it! It’s open source!