Status.js: Work well with messages

I talked briefly about my javascript library StatusJS in the article Tech Notes: Radiant 0.9.0 RC1, but thought that it would be good to take the time to introduce it in more detail as it is such a useful library.

We live in a time where Rails-style flash messages have become so common and annoying in web applications that they litter the webscape like confetti in the annual Thanksgiving day parade. Enough already! I know I just deleted that object! I know I just created a message!

Now a couple of folks have come up with creative ways of automatically hiding flash messages after a certain period of time or allowing the user to manually close the message, but both solutions have the annoying effect of causing the content underneath to “slide up” once the message disappears. This can be jarring for users that are working with content below the message.

Perhaps we need to rethink this whole concept. Maybe it is less important to tell the user what they have just done and more important to tell them about the work that is being done.

This is where StatusJS comes in. StatusJS provides a robust solution for displaying progress messages to users while the work is being done. So instead of displaying “Changes saved.” in a flash message after the form is submitted, you display “Saving changes…” while the form is submitting.

A bit of a paradigm shift mind you, but something that Web applications should have borrowed from desktop applications a long time ago.

So how does it work?

StatusJS defines a couple of global functions that make it easy to control the status overlay, as the following code sample demonstrates:

showStatus("Initializing...");
setStatus("Loading graphics...");
setStatus("Finished!");
hideStatus();

The showStatus() function displays and centers a new status overlay, setStatus() changes the status message and re-centers the overlay, and hideStatus() hides the status overlay completely.

StatusJS also includes a LowPro behavior for forms that makes it easy to add onsubmit status messages when a user clicks a submit button.

To automatically connect the behavior with your forms, add the following line to your application.js file (assuming you are doing Rails development):

Event.addBehavior({'form': Status.FormBehavior()});

This allows you to add a custom attribute to each of your forms that contains the onsubmit status message:

<form action="/controller/action" onsubmit_status="Saving Changes...">
  ... contents of form ...
</form>

The form above would display a “Saving Changes…” progress message after the user clicked the submit button.

There are a couple of additional configuration variables that are worth noting. Normally you should set these variables in your application.js file (assuming you are doing Rails development). It is essential that application.js be loaded after status.js so that the variables are not overridden by the defaults. Here is how it works:

// The size of the corner images. A value of 12 means square
// 12x12 pixel corners.
Status.CornerThickness = 12;

// The path, width, and height of the spinner image
Status.SpinnerImage       = "/images/status_spinner.gif";
Status.SpinnerImageWidth  = 32;
Status.SpinnerImageHeight = 33;

// The background and corner image paths
Status.BackgroundImage  = "/images/status_background.png";
Status.TopLeftImage     = "/images/status_top_left.png";
Status.TopRightImage    = "/images/status_top_right.png";
Status.BottomLeftImage  = "/images/status_bottom_left.png";
Status.BottomRightImage = "/images/status_bottom_right.png";

// Dim the background when a status message is displayed. Also
// prevents stray mouse clicks from having any effect.
Status.Modal = true;

At the moment, StatusJS requires prototype.js, effect.js, and lowpro.js (all included in the GitHub project), but Sean Cribbs is working on a JQuery port. It will be added to the main project once it is ready for general use.

You can download StatusJS from GitHub here. The project includes a small demo in the test directory that requires Serve.

© 2013 John W. Long