Eric Hynds

Senior Solutions Enginner at Brightcove

← all posts

A jQuery UI Growl/Ubuntu-like Notification Widget

Wednesday, May 12, 2010

Update 7/6/2010: version 1.4.1 is out!

There are about a dozen other plugins out there that do this already, except most seem to come with an enormous footprint: 10-12k of code, X-number of images, and roughly 1000 options to support every plausible use case. For other minimalists like myself out there, here's one built off the jQuery UI widget factory in approx. 110 lines of code and 100% CSS. In typical widget fashion, this implementation supports the most basic (and arguably most common) uses, but is flexible enough for more advanced cases.

Example

Internet Explorer is a big-time downer with no HSLA/border-radius/box-shadow support, so if eye candy is important to you in IE, a transparent png background or similar can be added without much effort.

Usage

Using this widget is a simple four step process:

Step 1:

Include the JavaScript and CSS dependencies. Only the widget factory from jQuery UI is required.

  1. CSS file: ui.notify.css
  2. jQuery and the jQuery UI widget factory: ui.widget.js
  3. This widget: ui.notify.js

Step 2:

Create a container element to hold notifications, and a template from which all notifications will be constructed from. With this, you can have multiple containers on the same page holding different styles of notifications. Each container can contain different templates.

<!-- set the container hidden to avoid a flash of unstyled content
when the page first loads -->
<div id="container" style="display:none">
  <!-- 
  Later on, you can choose which template to use by referring to the 
  ID assigned to each template.  Alternatively, you could refer
  to each template by index, so in this example, "basic-tempate" is
  index 0 and "advanced-template" is index 1.
  -->
  <div id="basic-template">
      <a class="ui-notify-cross ui-notify-close" href="#">x</a>
      <h1>#{title}</h1>
      <p>#{text}</p>
  </div>

  <div id="advanced-template">
      <!-- ... you get the idea ... -->
  </div>
</div>

Once the widget is initialized on the container, each template is cached and removed from the DOM. You can add one or more close links in your template by assigning each anchor the class ui-notify-close. The close link in this example has additional styling through the class ui-notify-cross, which makes the "x" look like an icon.

Define any variables you want to include in this template using #{varname} syntax. You can call these anything you'd like.

Step 3

Initiate the widget on the container, optionally passing in a hash of default options:

// basic
$("#container").notify();

// or with options (there are only 2)
$("#container").notify({
  speed: 500,
  expires: false
});

Step 4

Notifications are actually displayed by calling the create method. Pass in an hash of variables to transpose into the template:

// notice the templates in step 2 are expecting title and text variables.
// you can add as many as you like, and call them whatever you want.
$("#container").notify("create", {
  title: 'Test Notification',
  text: 'This is an example of the default config, and will fade out after five seconds.'
});

If you'd like, set specific options for each notification by passing in a second hash:

// example of overriding the expires and speed options for one notification
$("#container").notify("create", {
  title: 'Test Notification',
  text: 'This is an example of the default config, and will fade out after five seconds.'
},{
  expires: false,
  speed: 1000
});

You can specify the template to use by passing in the ID of the template as the second parameter. This is optional, and if not provided the first template defined will be used. Alternatively, you can pass in the index of the template in the container as the second argument.

// create a new notification using the "basic" template
// that we defined in step 2.
$("#container").notify("create", "basic-template", { /* template vars */ });

// we can refer to the template by index as well.  this
// statement is equivalent:
$("#container").notify("create", 0, { /* template vars */ });

The create method returns a notification instance object with two public methods: open and close.

// create a new "sticky" notification
var instance = $("#container").notify("create", {}, { sticky:true });

// close it
instance.close();

// re-open it
instance.open();

Options

These options can be set for all notifications within a container, or on a notification-by-notification basis:

Parameter Description Default
speed The amount of time in milliseconds to fade notifications in and out. 500
expires Notifications will automatically close after this amount of time, in milliseconds. Set to 0 or false to create a "sticky" notifications. 5000
stack
New in version 1.2.1!
Notifications will stack downwards if set to "below" (default), or upwards if set to "above."
below
custom
New in version 1.3!
A boolean value denoting whether or not the widget should apply its own styling classes. Set to false to roll your own notification themes (including ThemeRoller). You could simply overwrite the included CSS, but using this option allows you to create default AND custom notifications within the same containers, as well as maintain a clear upgrade path as you won't have to touch any of the included files.
false

Events

These events can be bound by passing handlers in as options. Example:

// for a specific notification
$("#example").notify("create", { /* template vars */ },{
  open: function(){
    console.log("Notification opened!");
  }
});

// or for all notifications within a container
$("#container").notify({
  open: function(){
    console.log("Notification opened!");
  }
});
Event Description
beforeopen Fires before the notification opens. If false is returned inside this callback, the notification will not open.
open Fires after the notifcation opens.
close Fires after the notifcation closes.
click Fires if the user clicks anywhere in the notification itself (not on the close link(s), if present). Useful if you want to close the notification or perform some other action once the user has acknowledged the notice. The callback receives two parameters as arguments: the event object, and the notification instance object. Example: js $("#container").notify("create", { title: 'Clickable Notification', text: 'Click on me to fire a callback' },{ click: function(e,instance){ // close the notice if the user clicks anywhere inside it instance.close(); } });

FAQ

How do I use ThemeRoller in my templates?

First, create a template and apply the appropriate ThemeRoller classes, icon classes you want to use, etc.:

<div id="notification-container">

   <div id="themeroller" class="ui-state-error">
      <!-- close link -->
      <a class="ui-notify-close" href="#">
         <span class="ui-icon ui-icon-close" style="float:right"></span>
      </a>

      <!-- alert icon -->
      <span style="float:left; margin:2px 5px 0 0;" class="ui-icon ui-icon-alert"></span>

      <h1>#{title}</h1>
      <p>#{text}</p>
   </div>

   <!-- other templates here, if you'd like.. -->
</div>

Next, either when you init the widget or create a notification, ensure the custom parameter is set to false:

// prevent notify from imposing its own styling classes
// on ALL notifications inside this container 
var handler = $("#notification-container")
  .notify({ custom:true })
  .notify("create", { title:"foo", text:"bar" });

// or just themeroller templates
var handler = $("#notification-container")
  .notify()
  .notify("create", "themeroller", { title:"foo", text:"bar" }, { custom:true };

Any link, button, etc. with the class ui-notify-close will close the notification when clicked. To use the X close link as seen in the demos, apply the ui-notify-cross class as well:

<a class="ui-notify-close ui-notify-cross" href="#">x</a>

How do I avoid a FOUC (flash of unstyled content) when the page first loads?

Simply give your container the display: none; CSS property. Once you initialize this widget on the container, it'll take care of the rest.

comments powered by Disqus