Building (clean) dashboards for your web app

Update January 2nd 2012: This example was created in 2008. There’s now an updated version using jQuery UI Portlets.

This post was partly inspired by Francesco Sullo’s comment on the difficulties on finding a balance between functionality and accessibility, but the content is for whoever may find it useful.

I know its easy to whine and complain about a problem and not do anything about it, so I thought about being part of the solution. This can be applied to pretty much whatever you have in mind. I’m going to be as generic as possible so you can place whatever you want inside each of the content segments. From tables to lists to forms to images.

There are probably going to be a whole lot of bugs and such, but that’s because this whole thing was put together within the span of a couple of hours. With more time, I’m sure the bugs can be worked out. And since everyone’s going nuts for “widget” functionality, I’ll see what I can do.

Once again, this is only an example. Your situation will demand you take it apart piece-by-piece and put it back together. This is not meant to be a drop-in replacement for someone else’s project! I didn’t do any bug-testing at all on this. In fact, my coffee was still hot when I finished… So use it at your own risk!!

The HTML

Believe it or not, the presentation of your content will be easy depending on how logical its arrangment is. That is to say, make the content logically partitioned ahead of time so you won’t need to work extra hard to present it later.

  • Title

  • Navigation

  • Content section

    • Segment1
    • Segment2
    • Segment3
    • Segment4
    • Segment5
  • Content footer

While you are building the page content, it’s ok to think about how you want it arranged. But don’t arrange it yet! Which means, don’t flood your page full of style elements and JavaScript. Leave that for the end, when your content is complete and you are ready to style the whole page.

In the content area, you can think of how you want to arrange your segments. In my case, I’m picturing a tab based page where each tab will have three columns. The content segments will go into blocks inside these columns. But I want to make the whole page accessible for people who may not have JavaScript enabled. The content should still be usable for anyone who browses the page.

The basic scaffolding I’m going to use.  As Phillip J. Fry would say, it looks like whale barf. But that’s because it hasn’t been styled yet.

The Styles

Tabs styles are are dime a dozen these days, but I’m going to use a technique similar to A List Apart Sliding Doors in that I will only use two images for the tabs and a couple more for the content background. I didn’t bother making them fancy or anything and it’s just a few minutes spent in Photoshop.

To apply the tabs, we need to give a few class names to the navigation list:

  <ul class="nav">
  <li class="active"><a href="">Home</a></li>
   <li><a href="">Articles</a></li>
   <li><a href="">Forums</a></li>
   <li class="na">
     <a href="">
     <img src="img/add_tab.png" alt="Add a tab" />
    </a>
  </li>
 </ul>

…And I’m reminded, once again, how much I dispise the WordPress text editor for typing code.

Notice that I changed the last “Add a tab” link into an image. If you do the same, just remember to give the image an “alt” value. Or else, people who have images disabled or are viewing in a browser that doesn’t have image capability will be left out.

Now let’s see what it looks like after we add the tabs.

Slightly better looking whale barf, I’d say. But there still aren’t any columns yet.

The Framework

One of the hard parts of building a dashboard is selecting your code libraries for rich UI functionality. There are literally thousands of code libraries that deal with this one way or another. But only a few that have gone into creating a complete set that you can use.

The two most popular are Prototype and jQuery. The least cumbersome and, as far as I can see, least intrusive of these is jQuery. Of course not everyone will agree, so flame away.

Instead of writing all of the widget functionality from scratch, I’ll be using the jQuery UI framework to build virtually all of it. When I’m done, I will only have two JS code files that I’ve written myself and only one of them will have true functionality in it. The other will just be a loader similar to the script.aculo.us loader in principle, but a hundred times simpler.

Specifically, I’ll be using the sortable plugin. Unfortunately, to use this plugin, we need to call 5 seperate code files including the jQuery main code file (this is one of the big reasons why I have an issue with JavaScript heavy sites).

To lessen the load a bit, I’m going to use a loader and a seperate JS file for the dashboard “stuff”. You’re probably thinking, “why would you add another JS file to this? Doesn’t that make the load size bigger?” Hold on, there’s a method to the madness.

Keep your head clean

I’m serious!

Even if you look at the source of this page, you’ll see a ton of junk in the <head> tag. That’s WordPress for ya! Granted, this is for all their dashboard stuff, but I think they could really use more streamlining.

For this example, I’m only putting one stylesheet and two JS files in the header. That’s all that you need and that’s all that’s acceptible. If your <head> tag is longer than 10 lines, then you’ve got more planning to do!

First, we include the jQuery base library and include a “Setup” JS file. This is what will call all subsequent JS files into the page. There’s no sense in downloading all those files if your browser cannot support it. If it does support jQuery, then it will download the rest. If not, the script ends there and you’re not downloading any more files.

function loadJS(p) {
  $("head").append(
     '<script type="text/javascript" src="'+p+'"></script>'
   );
}

loadJS("js/jquery.dimensions.js");
loadJS("js/ui.mouse.js");
loadJS("js/ui.sortable.js");
loadJS("js/ui.sortable.ext.js");
loadJS("js/dashboard.js");

This code uses jQuery’s own “append” function to load the rest of the code files into the header. Notice the last line contains the “Dashboard” file.

The Code

The Dashboard JavaScript file contains everything we need to create our columns, convert all the “segments” into widget blocks and sort them into the columns.

Believe it or not, it’s actually much simpler to do it this way than to hard-code anything into your HTML file.

The first step is creating our columns…

$('.main').append('<div id="container1"></div>');
$('.main').append('<div id="container2"></div>');
$('.main').append('<div id="container3"></div>');
$('.main').append('<div style="clear:both;width:100%;"> </div>');

Again, we’re using the “append” function to load the columns to our page. The last <div> is there to clear our content. This is another reason why I prefer to keep this stuff in the code file and not clutter the HTML.

In our plain content page, you may notice a “title” and “description” class given to each of the titles and descriptions in each of the content segments. This is so jQuery has something to grab onto as we create our content blocks…

$('.main').find("div").each(function(i) {
  if(this.className == 'segment') {
    var t = '';
    var d = '';
    var c = '';

    $(this).find("*").each(function(j) {
      if(this.className == "title") {
        t += $(this).html();
        $(this).remove();
      }
    });
    $(this).find("*").each(function(j) {
      if(this.className == "description") {
        d = $(this).html();
        $(this).remove();
      }
     });
     c = $(this).html();
     var rcol = $(this).attr('rel');
     $('#container'+rcol).append(segBlock(t, d, c));
     $(this).remove();
   }
});

This code selects each and every “segment” in our content and loads the title, description and the content inside and then sends it over to the “segBlock” function. Once that’s done, there’s no reason to keep the segments on the page any more, so we use the jQuery “remove” function to get rid of them.

The “segBlock” function is basically a formatter. It can be anything you want. In my case, I wanted to create a block like arrangement. You can give it “widget” like functionality too by giving it a collapsible panel, an editable title and description and other stuff. I won’t go into the details of how to get all of that done. You can see how it’s done via the code file. All of these extra features can be added using jQuery.

Putting it all together

Finally, we can see what two codefiles, a stylesheet and a plain HTML file can do when you select the right tools for the job. There’s no need to jump through hoops to get any of this done. No reason why you can’t do this in a single evening or even a few hours.

The “Add a tab” link can be used to redirect the user to a control panel where new sections can be added. For this example, I haven’t used such a page, and instead used the “append” function again to add a new tab each time. In a real-life example, this should be done via a server-side personalization mechanism.

I’d recommend avoiding cookies for this purpose, since some people don’t enable them. Plus cookies are vulnerable to being hijacked. In fact, they are fare more susceptible than session hijacking. So that’s something to keep in mind while enabling personalization.

Also, the drag-n-drop functionality is completely optional. But as per my original description, I tried introducing some “widget” like behavior here and there.

Here’s a more realistic example. The images for the news widget were courtesy of the Tango Desktop Project.

Well, that’s all I have for you today…
Hopefully you carried something away that will help you put together a dashboard for your own app.

About these ads

16 thoughts on “Building (clean) dashboards for your web app

  1. Hey very nice article, y there aposibilitty to have the hole thing in a zip or a rar file, I´m trying to make it working but something is not working.

    Thanks in advance

  2. Hi Fabian.

    I would have created a zip file, but my idea was to put together a set of steps where people can create their own solutions from scratch.

    That’s why I said “This is not meant to be a drop-in replacement for someone else’s project” ;)

    I do use a lot of the techniques shown here on another example.

    Maybe I will create an all-in-one application that will use everything shown here.

    I’m just a little short of time ;)

  3. Pingback: The web 101 beginner? Intermediate? or Advanced? « Joomla! Newyork

  4. Pingback: My guide to forums 101: how the moments should be remembered « Joomla! Newyork

  5. Pingback: JavaScript dynamic library loader « This page intentionally left ugly

  6. Pingback: Eric Blue’s Blog » Weekly Lifestream for June 20th

      • Thank you for your prompt response, eksith. I just realized that the corporate firewall that I’m behind is now blocking DNS lookups randomly “for security reasons”. Time to proxy the connection. I’m sorry for the inconvenience!

  7. Pingback: Building a jQuery UI Dashboard « This page intentionally left ugly

  8. Pingback: Building Completely Tabeless WebPart Control + Drag and Drop | Colour Blend Creative

  9. Even ancient tribes used to utilize coconut oil for the nourishment of their hair.
    If enzymes are added to it, it can prove to be a welcome alternative to those medications that contain very large quantities of chemicals in them.
    Taking coconut oil increases your energy level and burn off calories at an
    accelerated rate.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s