Friday, November 10, 2006

Creating a Google Gadget Tips-Like Widget

I recently had to rebuild my laptop which meant reinstalling software including the very useful Google Desktop.

During the installation, the Desktop installed Google Gadgets and the "tips" dialog --

Basically, the dialog is a series of help screens accessed by mousing over the vertical tabs. You really can't put too much information in each pane, but I thought that the vertical tabs were unique and worth imitating for a web application.

To do that, I'll use the
Bindows JavaScript toolkit. Originally created by Erik Arvidsson, it's an incredibly complete and powerful DHTML/Ajax framework for building web applications. It's definitely not the only one around (i.e. Dojo, Tibco's General Interface, etc.), but I use it everyday and I'm pretty familiar with it.

(For this post, I'm not going to go into the basics of how to build a Bindows application. Yoram Meraiz and his Team at MB Technologies have great
tutorials and a lot of examples to get you started.)

Whenever I "imitate" or prototype something, the first thing I do is look at the behavior of the thing. All the visualizations (i.e. the "pretty" things) come last. So, from the Google's help dialog, we know that our model --

  • Will listen for events (i.e. mouseover a tab and the pane changes)
  • Can be dragged (another event is dispatched)
  • Can be closed by clicking a button
  • Has text for each tab and the title of the dialog
  • Has images for content in each tab pane
With that we can map that functionality to our toolkit.

  • To listen for events, we will need a BiComponent
  • To drag the dialog, we will need a BiComponent
  • To close the dialog, we will need a BiButton (a derivative of BiComponent)
  • For the titles, we will need a bunch of BiLabels (another derivative of BiComponent)
  • For the content in the tab pane, we will need a bunch of BiImages (another derivative of BiComponent) as well

It's a pretty good bet that we'll use BiComponents.

The BiComponent is by far the most useful component in Bindows for a number of reasons --

  1. A BiComponent understands events. In other words, a BiComponent listens for and can dispatch events
  2. A BiComponent can add other BiComponents. This means that they can function as a group (i.e. they can be dragged, hidden together, etc.)
  3. A BiComponent can be styled inline (naughty, naughty) or by selector rules (i.e. via a CSS file or in Bindows parlance, a theme)

Let's take a look at how we use the BiComponent to imitate the Google help dialog.

First, we'll take advantage of the fact that we can add components together. So, we start out by creating a container to hold all the other parts of the dialog. Not surprisingly, the container is a BiComponent --

Then, we look at what should be in the container. The dialog's label and grabber area are no brainers. We'll use a BiLabel and a BiImage for those and add them to the container --

The same goes for the close button. It's easy --

Now, let's look at the tab button and the tab pane. They're related in that when you mouseover the button, the content changes in the pane. So, what we'll do is create another container that holds the tab button, the tab pane and the content.

We will repeat this for each tab (there are five). Of course, we'll need to add this to our container. One benefit of doing it this way, is that we can add all the tab components and then they can be positioned together in one shot.

Note that each tab is already built up. In other words, we're not going to build them up when they are needed (i.e. when a mouseover occurs). We'll just use the power of CSS and style them so that they do not display if they're not moused over --

For now, the code uses a lot of inline styles and as an early prototype, that's fine. Right now, what we're after is to imitate behavior and look and not the reuse or maintainence of the component. Eventually, when we take this prototype and make it a reusable component/widget, we'll worry about that.

Let's look at how we handle the behavior for the tabs. When we mouseover the tab button, a number of things happen --

  • The text in the tab button is bolded
  • The tab pane appears with the new content
  • The previously selected tab is no longer bolded and its content is no longer displayed

Here it is translated into code for one of the tabs --

The last behavior is dragging the dialog and doing that in Bindows is easy. We just add the container to a BiMoveHandle component --

We've omitted the close button, but essentially it listens for the onclick event and in our case, simply displays an alert box that says "Clicked!"

That's it. What we end up with is our implementation and you can view the full source here.

In an upcoming entry, I'll address how we can turn this prototype into something reusable so that you can use it in your own code (we'll also get rid of the inline styling too).

No comments: