| Subcribe via RSS

Notification Windows with JavaScript and AIR

December 15th, 2008 Posted in AIR, Ajax, HTML, JavaScript

While there’s a lot to consider when building notification windows, they are actually pretty easy because there’s minimal cross operating system (OS) differences for which you need to account. A common pairing with notification windows is system tray/docking which varies considerably across OS, and can be a little more challenging. More on that in a future post. For now however, let’s take a look at notification windows using JavaScript. We will walk through what a notification window looks like to AIR, and explore some of the various options you have when you want to alert the user.

If you look at the documentation for native windows with AIR, you’ll find a variety of different options. A “normal” window is what you might expect, a normal OS window with the typical operating specific chrome and handers. This will usually be a title bar, close/maximize/minimize buttons and a resize handle. If you are a Mac user, you’ll be very familiar with “utility” windows. Utility windows are usually what contains a tool palette or the likes, and consists of a slender title bar with some fashion of control (varies per operating system).

Finally is the “lightweight” window. This is a window without any chrome whatsoever. In the context of Adobe AIR, this is sometimes valuable; such as when you want to provide your own chrome. When it comes to a notification window, that’s pretty much exactly what you want to do – create a window without any chrome that appears for a specified duration and then closes itself. The “lightweight” window is the option we will use for notifications.

Before you go creating that window however, you will want to consider some other options on the window appearance. Any additional fine grain control you want over that window, as manifest during it’s creation, is set through a series of native window initialization options, which you’ll find in the NativeWindowInitOptions class. In the case of a lightweight window, there’s not much we need to specify here except that the type is indeed “lightweight”.

var options = new air.NativeWindowInitOptions();
 
options.type = air.NativeWindowType.LIGHTWEIGHT;
options.transparent = true;
options.systemChrome = air.NativeWindowSystemChrome.NONE;

You might also want to position your notification window in a specific location on the screen. There are two approaches here. The first is the Capabilities class, which through static properties can give you the screen resolution. If you want to account for the situation where the user has multiple screens, then you will want to use the Screen class. You can access the main screen and get the a Rectangle that represents the viewable space (i.e. taking into account the “start bar” on Windows). If you know how big the screen is, and you know how big your notification window is, you can position it wherever you would like.

var bounds = null;
var screen = air.Screen.mainScreen.visibleBounds;
 
bounds = new air.Rectangle(
	screen.width - WINDOW_WIDTH - 10,
	screen.height - WINDOW_HEIGHT - 10,
	WINDOW_WIDTH,
	WINDOW_HEIGHT
);

At this point, if you went and created a native window using the constructor (i.e. new NativeWindow()) then you’d get your window, but it’d have a Flash stage inside of it. That’s not going to help you use your HTML, JavaScript and CSS any. HTML applications in Adobe AIR display inside of an HTMLLoader instance. You can think of this as the browser’s viewport. The HTMLLoader class actually expects that you’ll want to create new native windows that contain HTML content, and provides a static convenience method to help you out.

var notification = air.HTMLLoader.createRootWindow( 
	true, 
	options, 
	false, 
	bounds 
);

The result of this call is an HTMLLoader instance – specifically, the HTMLLoader instance of the new window you just created. Keep in mind that it’s the viewport, not the native window itself. The HTMLLoader has some additional properties that you might want to set as well, especially in the case of a notification window. The main one is that you will want this notification to always appear over everything else so the user can see it. That is set by getting a reference to the native window, and then telling it to be “alwaysInFront”.

notification.paintsDefaultBackground = false;
notification.stage.nativeWindow.alwaysInFront = true;
notification.navigateInSystemBrowser = true;

The “paintsDefaultBackground” is an interesting property as well. In the case of any native window that is not using the system chrome, you can set the remainder of the window to be transparent. In the case of HTML, you will also need to tell the HTMLLoader, the browser viewport, not to use the default background of the HTML page that it would otherwise put in place. You don’t always need to use this option, but it is handy for cases where you want to infer some style through custom chrome.

The window you just created, whether it be a notification window, or other window, is not going to have any default content – it is just a blank window. The HTMLLoader provides two means to fill that window with content. The first is simply to send the viewport some HTML to display, which happens through HTMLLoader.loadString( yourHTML ). This is great for basic markup, but if you’re doing anything extensive, it will obviously get pretty cumbersome.

The other option then is to have a HTML page assembled that represents what you want your notification window to look like. You can tell your new native window to display that content by calling HTMLLoader.load() and passing a new URLRequest object. The URLRequest is simply a more formal wrapper around a destination to HTML content (content on the web in general, really). If your notification page is local, then you will use the appropriate notation, just like in any other web page. You can also point URLRequest at any other location on the web as well.

notification.load( new air.URLRequest( NOTIFY_SOURCE ) );
 
// Alternatively
// notification.loadString( "Foo.  Bar." );

You’ve finally got your native notification window, sitting pretty where you want it, looking like you want it, and filled with the content you want. The shortcoming now is that it does not go away all by itself. What you will need to do is keep track of how long the window has been open, and then tell it to close itself after that period of time has elapsed. The first question becomes who does the closing?

You have a reference to the native window in the originating application, and you could use that. In this case you also control what content that window is loading, so you could have the window watch our for itself. Generally speaking, I prefer the later as it seems more modular to have the notification window take care of dismissing itself.

The method to do this, regardless of the approach you take is NativeWindow.close(). If you are calling from the originating application, you’ll need to get a reference to the window itself through the HTMLLoader. Reference the code for setting the window to always be in front, as to how to get this access to the native window. If you are going to close the window from the page that is loaded, then “nativeWindow” is just another property like the traditional “window” and “document” properties.

// From within the notification window
nativeWindow.close();
 
// Alternatively, from the originating window
// notification.stage.nativeWindow.close();

Now that you can tell the window to close, you will need to know how long it has been open. You can use the traditional JavaScript method of setTimeout() here, which will work perfectly. Adobe AIR also offers us a more robust Timer class that I prefer to use. Keep in mind that you may not want to close the window automatically at all. Maybe you want to leave it on the screen until the user takes some action to dismiss the window. If that’s the case, don’t forget to include some fashion of button in your HTML page.

var timer = new air.Timer( DELAY, REPEAT );
 
timer.addEventListener( air.TimerEvent.TIMER_COMPLETE, doTimerComplete );
timer.start();
 
function doTimerComplete( evt )
{
	nativeWindow.close();
}

At this point, you have all the tools you need to get going with your own notification windows. I have put together a simple example and made the source available. The example creates a notification every ten seconds. The notification window removes itself after four seconds have elapsed. My notification window stays where I put it, but from here you might explore other options, such as letting the user move the window, and then remembering where they moved it to to the next notification shows up in the same place. The options with Adobe AIR, once you’re on the desktop and out of the browser are limitless.

2 Responses to “Notification Windows with JavaScript and AIR”

  1. Viorel T Says:

    If I want to pass an answer to originating window, based on user action he makes in notification window, how do I do that?


  2. Viorel T Says:

    Thank you for your time!


Leave a Reply