dojo.connect

The first dojo.connect online conference is coming up this week February 10-12, 2010. I’ll be giving a talk about Debugging Dojo Applications. I’ll be covering the following:

  • Common mistakes and how to avoid them
  • Web browser debug tools
  • Built-in Dojo debugging tools
  • Methods for finding and fixing syntax issues or malformed data
  • Writing tests to trap specific bugs

There is still room left, so head over to http://www.widespreadconferences.com/ and sign up today!


I saw a really neat lightweight lightbox a while ago and decided to make a version for Dojo. I’ve dubbed this version the LightboxNano because it is under 2K over the wire after a build and being gzip’d.

The LightboxNano is not a dijit._Widget. It is designed to be very lightweight and only requires Dojo core and dojo.fx. The LightboxNano was coded for Dojo 1.2, but should work with past versions with little or no modifications.

Features

For being so small, it packs a handful of features:

  • Automatically resizes large images to fit in browser window.
  • Preloads the larger image to make loading faster.
  • Keyboard accessible.
  • Instantly makes your website awesome.

Example

The LightboxNano is really easy to use. Here’s an example:

<script src="/path/to/dojo.js" type="text/javascript"></script>
<script type="text/javascript">
    dojo.require("dojo.parser");
    dojo.require("dojox.image.LightboxNano");
</script>

<a dojoType="dojox.image.LightboxNano" href="/path/to/large/image.jpg">
    <img src="/path/to/small/image.jpg">
</a>

To see it in action, click the image below:

Styling

When the LightboxNano is created, it adds two <div> tags inside the anchor tag: one for the enlarge icon and one for the loading icon. For example, you can define styles like this:

a:hover .dojoxEnlarge {
    display: block !important;
}
.dojoxEnlarge {
    background: url(images/enlarge.png) no-repeat 0 0;
    top: -5px;
    left: -5px;
    margin: 0 !important;
    width: 16px;
    height: 16px;
}
.dojoxLoading {
    background: #333 url(images/loading-dark.gif) no-repeat center center;
    border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    border: 2px solid #000;
    height: 24px;
    opacity: 0.8;
    filter: alpha(opacity=80);
    padding: 6px;
    width: 24px;
}

Usage

You can declaratively create the LightboxNano using a dojoType on an <a> or <img> tag. Or you can choose to programatically create the LightboxNano:

<script type="text/javascript">
    dojo.addOnLoad(function(){
        new LightboxNano({
            href: "/path/to/large/image.jpg"
        }, "myLink");
    });
</script>

<a id="myLink" href="/path/to/large/image.jpg">
    <img src="/path/to/small/image.jpg">
</a>

If you want to access it for some reason, you’ll need to use its jsId.

Parameters

href – String
URL to the large image to show in the lightbox.

duration – int
The delay in milliseconds of the LighboxNano open and close animation.

preloadDelay – int
The delay in milliseconds after the LightboxNano is created before preloading the larger image.

File Sizes

The LightboxNano is pretty small, but it relies on several other core Dojo components. If you do a custom Dojo build containing the LightboxNano and dojo.parser, the dojo.js is 96KB. If you enable HTTP compression on the web server, you can get that down to a nice 32KB.

Limitations

  • The LightboxNano does not reposition itself when the browser window is resize or scrolled.
  • In IE6, drop down select lists bleed through the LighboxNano layer. This can be fixed with an iframe shim. This was skipped to keep the size down and because we all want IE6 to just go away.

Future Improvements

There’s always things that can be done to improve the LightboxNano. Here’s a couple ideas and you’re welcome to make suggestions in the comments.

  • Add support for displaying a caption.
  • Add support for dojox.embed to play Flash or Quicktime movies.

Try it Today!

You can download the LightboxNano files here: LightboxNano.tar.gz [594KB]. Soon, the LightboxNano will be in dojox, so you won’t need to install it separately.

You can view the original test page here: http://download.dojotoolkit.org/release-1.3.1/dojo-release-1.3.1/dojox/image/tests/test_LightboxNano.html.

If you end up using the LightboxNano, feel free to link to your site so everyone can see your new awesome website!


I recently had to integrate search capabilities into a website I worked on. I chose to use the Google AJAX Search API. I needed the form field display to be very customized and clean. I do leverage the Dojo Javascript Toolkit to help with the boilerplate DOM and event stuff.

Search Form

The first thing you need to do is sign up for a new key:

Sign-up for an AJAX Search API Key

Once you get the key, you’re ready to start coding your own custom search form.

Begin by adding the the following to your <head> tag:

<script src="http://www.google.com/jsapi?key=<KEY GOES HERE>" type="text/javascript"></script>

Since my example uses Dojo, you need to include Dojo for my code to work. If you don’t already use Dojo, you can simply include it by adding the following to the <head>:

<script src="http://o.aolcdn.com/dojo/1.1.1/dojo/dojo.xd.js" type="text/javascript"></script>

Next we need to add our code that performs the search. First tell the Google API to load the search API:

<script type="text/javascript">
google.load("search", "1", {"nocss":true,"nooldnames":true});

Next we need to initialize our page when the page loads:

dojo.addOnLoad(function(){
    var results = dojo.byId("results");
    var cursor = dojo.byId("cursor");
    var ws = new google.search.WebSearch();
    ws.setNoHtmlGeneration();

Be sure to set the domain you want to search. The LARGE_RESULTSET will return the maximum number of results Google allows, which is usually 8 results.

    ws.setSiteRestriction("example.com");
    ws.setResultSetSize(google.search.Search.LARGE_RESULTSET);

Next we need to tell the WebSearch object the function we want called after the results are returned. The 3rd argument to setSearchCompleteCallback() is an array with a reference to our WebSearch instance. This array gets passed to our callback function when the callback is fired.

    ws.setSearchCompleteCallback(null, function(w){
        if(!w.results){return;}
        results.innerHTML = "";
        cursor.innerHTML = "";
        var d = dojo.doc.createElement("div");
        results.appendChild(d);
        for(var i=0,len=w.results.length; i&lt;len; i++){
            var r = w.results[i];

Our WebSearch object has a createResultHtml() function that creates an the DOM nodes of our result, but it adds a bunch of crap and forces the result to open in a new window. So, to fix that, we use Dojo to go clean up the nodes before adding them to the page.

            w.createResultHtml(r);
            if(r.html){
                var n = r.html.cloneNode(true);
                dojo.query(".gs-visibleUrl", n).forEach(function(p){
                    p.parentNode.removeChild(p);
                });
                dojo.query(".gs-watermark", n).forEach(function(p){
                    p.parentNode.removeChild(p);
                });
                dojo.query("a", n).forEach(function(p){
                    if(p.getAttribute("target")){
                        p.removeAttribute("target");
                    }
                });
                results.appendChild(n);
            }
        }
        if(w.cursor){
            var cn = dojo.doc.createElement("div");
            cn.className = "gsc-cursor";
            var label = dojo.doc.createElement("div");
            label.innerHTML = "Pages:";
            label.className = "label";
            cn.appendChild(label);
            for(var i=0, len=w.cursor.pages.length; i&lt;len; i++){
                var pn = dojo.doc.createElement("div");
                pn.className = "gsc-cursor-page";
                if(i == w.cursor.currentPageIndex){
                    pn.className += " gsc-cursor-current-page";
                }
                pn.innerHTML = w.cursor.pages[i].label;
                pn.idx = i;
                dojo.connect(pn, "onclick", function(evt){
                    ws.gotoPage(evt.target.idx);
                });
                cn.appendChild(pn);
            }
            cursor.appendChild(cn);
        }
    }, [ws]);

If you want to execute a search when the page loads, then you can fire execute() with the criteria.

    ws.execute("");

Finally we need to wire up the search button and form. We don’t care about the event details, we just want to execute the search for the current value in the search criteria field.

    function query(evt){
        dojo.stopEvent(evt);
        ws.execute(dojo.trim(dojo.byId("searchCriteria").value));
    }
    dojo.connect(dojo.byId("searchButton"), "onclick", query);
    dojo.connect(dojo.byId("searchForm"), "onsubmit", query);
});
</script>

In the body of your page, add the following markup to define the form:

<div>
    <form id="searchForm">
        <input type="text" autocomplete="off" id="searchCriteria" value=""/>
        <a href="#" id="searchButton"><span>Search</span></a>
    </form>
</div>
<div id="results"></div>
<div id="cursor"></div>

For clarity, I removed all styling. One thing you’ll notice is the “Search” button is an <a> tag instead of an <input> tag so that it could be more easily be styled.

Aside from our text field and search button, there are some CSS styles you can tweak for the search results and pagination:

<style type="text/css">
.gs-result{padding:6px 0;}
.gsc-cursor{display:inline;padding:10px 0;}
.gsc-cursor .label{color:#000;display:inline;font-weight:bold;margin-right:8px;}
.gsc-cursor-page{cursor:pointer;color:#00F;display:inline;margin-right:8px;
text-decoration:underline;}
.gsc-cursor-current-page{color:#000;font-weight:bold;text-decoration:none;}
</style>

That’s all there is to it. Load the page up and do a search!

Search Results

I’ve been sitting on this code for a while and decided to clean it up and submit it to the Dojo Javascript Toolkit.

The RotatorContainer cycles through dijit.layout.ContentPanes and provides navigation in the form of tabs or a pager. There a number of timing settings you can adjust as well as the layout of the controls.

Give it a try!

Here’s how you can use it:

<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dijit.layout.ContentPane");
dojo.require("dojox.layout.RotatorContainer");
</script>

<div dojoType="dojox.layout.RotatorContainer" id="myRotator" showTabs="true"
      autoStart="true" transitionDelay="5000">
    <div dojoType="dijit.layout.ContentPane" title="1">
        Pane 1!
    </div>
    <div dojoType="dijit.layout.ContentPane" title="2">
        Pane 2!
    </div>
    <div dojoType="dijit.layout.ContentPane" title="3">
        Pane 3!
    </div>
</div>

NOTE: There is some CSS needed to make the RotatorContainer look correct. Include or copy the contents of the dojox/layout/resources/RotatorContainer.css into your CSS file.

The magic happens once you have some content. It takes a bit of time to tweak things, but you can pretty much do anything you can imagine.

The RotatorContainer can be controlled by a pager which includes a play/pause button, next and previous button, and the current and total panes. You can also have as many pagers as you’d like. The pager code looks like this:

<script type="text/javascript">
dojo.require("dijit.form.Button");
</script>

<div dojoType="dojox.layout.RotatorPager" rotatorId="myRotator">
    <button dojoType="dijit.form.Button" dojoAttachPoint="previous">Prev</button>
    <button dojoType="dijit.form.ToggleButton" dojoAttachPoint="playPause"></button>
    <button dojoType="dijit.form.Button" dojoAttachPoint="next">Next</button>
    <span dojoAttachPoint="current"></span> / <span dojoAttachPoint="total"></span>
</div>

One thing I should note, if this widget should find it’s way into dojox, it’s possible the name or functionality will change.

If time permitted, I would have liked to add additional transitions such as a left-to-right wipe. Oh well.

Enjoy!


Dojo 1.0 is out now and you know what that means… version 2.1 of the Dojo Toolkit Module is now available with support for Dojo 1.0. There’s been a bunch of testing and it looks to be pretty solid, so give it a shot:

What’s new in v2.1:

  • Upgraded Dojo code to Dojo 1.0.0
  • Added option to force Dojo to load on all pages
  • Fixed bug with applying profile weights
  • Fixed bug with Dojo Toolkit Module settings page in IE
  • Fixed bug displaying duplicate roles for each profile on settings page
  • Fixed typos in documentation
  • Added stripos() function for PHP4 users

For additional information, visit the Dojo Toolkit Module project page at http://www.cb1inc.com/open-source/dojo-toolkit-module. The documentation has been updated to cover the latest features. If you should have any issues, please report them in the forum.


It has been a couple months since the last post and there has been much going on. For starters, version 2.0 of the Dojo Toolkit Module for Drupal has been released. It has undergone a bunch of testing and looks pretty good.

dojo_toolkit_module-5.x-2.0.tar.gz (52.5KB)

What’s new in v2.0:

  • Added support for Dojo 0.9.0
  • Added support for defining a Dijit theme
  • Includes build profiles for local and CDN custom builds
  • Fixed bug with support for prefixed table names
  • Changed license from GPLv2 to AFL/BSD

I know it doesn’t seem like much and I might be forgetting a few items, but with the port from Dojo 0.4.3 to Dojo 0.9.0, a lot of code was re-written.

In addition, I decided to change the license for this module to the same license as the Dojo Toolkit because it just didn’t feel like the Dojo Toolkit Module had the same spirit as Dojo. Since this module is no longer GPLv2, I cannot submit this module to Drupal’s CVS repository.

The Dojo Toolkit Module has a new home at http://www.cb1inc.com/open-source/dojo-toolkit-module. The documentation is partially updated. The build profiles and editor profiles information is a little out of date. All of the examples are still Dojo 0.4.3, but I’ll be updating these soon. If you should have any issues, please report them in the forum.

In other news, the CB1, INC. website received a much needed face lift. It is still not 100% IE friendly, but it is better than before. If time permits, I could fix it, but it is certainly not a high priority.

Finally, we have started two new open source projects. The first is a nameless content management system. There are tons of CMS applications out there, but I think there is still room for improvement. The other project is Coma, an enterprise comet server. There will be more information about these two projects in the near future.


I’ve had v1.2 almost done for a couple months, but I just didn’t have the time to polish it up. Well, good news! It’s done!

So, whats new?

  • Added uninstall logic
  • Fixed access roles for both config and editor profiles
  • Fixed visibility for both config and editor profiles
  • Fixed tree images pre-loading URLs on Subversion repository page
  • Added support for Dojo Toolkit 0.4.3
  • Added ability to tie config profiles to pages
  • Removed support for djConfig.debugAtAllCosts – didn’t work anyways

The Dojo Toolkit Module homepage can be found at http://code.google.com/p/dojo-toolkit-module/. The documentation has not been updated and still refers to v1.1. I’m planning on skipping the v1.2 documentation updates and wait until v1.3 is done, then do a bunch of updates to the documentation. If you should have any issues, please report them in the forum.

Recently the Dojo Toolkit gang has released 0.9 beta and I’ve already begun working on v1.3 which switches from v0.4.3 to v0.9 and should have another release soon!


I just got back the other day from the Dojo Developer Day in New York on May 4th-5th and needless to say, it was great! The event is broken into 2 days: one for Dojo contributors and one for the Dojo community.

For me, the big talk of the first day was Dojo 0.9 which includes the new Core and Dijit systems. From the sounds of things, Dojo’s new core is much, much smaller and faster. Dijit is the new widget system that also improves size and speed, but also much improved skinning capabilities.

On Saturday, I did a short presentation on the Dojo Module and talked briefly about some of the other Dojo enhanced Drupal modules in the pipe. I spent a lot of time in smaller discussion groups talking about Drupal and Dojo development.

Both days were filled with great talks and great demos. Seeing and learning about all the code side of things is great, but the best part is meeting and hanging out with the Dojo gang!


After adding some features and fixing some bugs, version 1.1 of the Dojo Toolkit Module for Drupal is available for download!

Read the release notes for the specific changes. The Dojo Toolkit Module homepage can be found at http://www.cb1inc.com/open-source/dojo-toolkit-module. The documentation has been updated to reflect the additions. If you should have any issues, please report them in the forum.

Very soon we’ll be releasing some Drupal modules that use the Dojo Toolkit Module, so stay tuned! In the meantime, enjoy version 1.1!