Dialogs in XULRunner

The last article in this series covered some simple XUL for creating windows, menus, and toolbars. This time I'll look at dialogs, including both custom dialogs and standard operating system dialogs. Dialogs are pretty fundamental to a desktop application. Certain types of dialogs are used so frequently that the OS can provide a default implementation. File open and save dialogs are good examples of these. Whenever possible, it is a good idea to reuse these "native" dialogs so users get a consistent experience across applications.

Custom dialogs

Building dialogs in XUL is very similar to creating windows. Each dialog is described in its own XUL file. XUL provides a dialog element to act as the container for the dialog. Dialog XUL files can have DTD, CSS, and JavaScript, just like windows. Here is an example XUL dialog:

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<dialog id="myDialog" title="My Dialog"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        onload="window.sizeToContent();"
        buttons="accept,cancel"
        buttonlabelaccept="Set Favorite"
        buttonaccesskeyaccept="S"
        ondialogaccept="return doSave();"
        buttonlabelcancel="Cancel"
        buttonaccesskeycancel="n"
        ondialogcancel="return doCancel();">

  <script>
    function doSave(){
     //doSomething()
     return true;
    }

    function doCancel(){
      return true;
    }
  </script>

  <dialogheader title="My dialog" description="Example dialog"/>
  <groupbox flex="1">
    <caption label="Select favorite fruit"/>
    <radiogroup>
      <radio id="1" label="Oranges because they are fruity"/>
      <radio id="2" selected="true" label="Strawberries because of color"/>
      <radio id="3" label="Bananna because it pre packaged"/>
    </radiogroup>
  </groupbox>

</dialog>

XUL window elements have a special method to open dialogs, called window.openDialog(). Here is the code needed to open a dialog:

function openDialog() {
  window.openDialog("chrome://basicapp/content/dialog.xul", "newdlg", "modal");
}

The resulting dialog looks like this on Windows 2000, and will look similar on other operating systems:

Image:XULDialogExample.png

The first thing that caught my eye about dialog is the button-related attributes on the element. In an effort to make things easier for developers and more consistent for users, XUL has a mechanism to automatically create and position the core dialog buttons ("OK," "Cancel," and "Help" for example).

The developer just declares the need for the button, the button's caption, and the access key for the button, as well as the JavaScript function to call if the button is pressed. XUL handles placing and styling the buttons on the dialog. This is also nice for cross-platform applications, as each OS has its own convention for where buttons should be placed on a dialog.

Here is a short list of the button attributes on dialog; see also Creating dialogs at MozillaZine knowledge base:

buttons
A comma separated list of buttons to show on dialog (accept, cancel, help, extra1, and extra2).
buttonlabelaccept
Label for the accept button; similar attributes exist for the other button types.
buttonaccesskeyaccept
Access key for the accept button; similar attributes exist for the other button types.
ondialogaccept
JavaScript to execute if the accept button is pressed; similar attributes exist for the other button types.

XUL has a wide range of input controls you can use in a dialog. In the future, I will try to go into more detail on some of the existing and planned XUL input controls. Not too sure if I’ll use the <dialogheader>, but if I did, the single element would be a big time saver over building the header from scratch.

Common dialogs

Some of the most frequently used common dialogs are for opening and saving files. For instance, Windows has supported built-in file open and file save dialogs for many years, and the Macintosh has always had them. It makes creating an application easier for developers; in addition, the consistent user experience also makes applications easier to use. XUL supports native implementations of filepickers (Mozilla terminology for File Open and Save dialogs). Newer releases will allow using preferences to switch to a XUL emulation filepicker, if you want to. The XUL filepickers are XPCOM components and must be instantiated before using, like this:

function doFileOpen() {
  /* See: http://developer.mozilla.org/en/docs/XUL_Tutorial:Open_and_Save_Dialogs */

  var nsIFilePicker = Components.interfaces.nsIFilePicker;
  var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);

  fp.init(window, "Open File", nsIFilePicker.modeOpen);
  fp.appendFilters(nsIFilePicker.filterText | nsIFilePicker.filterAll);

  var res = fp.show();
  if (res == nsIFilePicker.returnOK) {
    var thefile = fp.file;
    alert(thefile.leafName);
    // --- do something with the file here ---
  }
}

XUL does not currently support any other common dialogs. That could change in future releases. Firefox and Thunderbird both support nearly native Page Setup and Print dialogs. However, XUL does support elements to make creating wizards a simple task as well.

Future articles in this series will look at input controls, printing, the clipboard, and XPCOM.

See also

Original Document Information

  • Author: Mark Finkle
  • Last Updated Date: October 2, 2006