Dialog Plugin

The Dialog() base class creates a new plugin that can be used to create a dialog plugin. For more information on base classes in general check out the base class guide.

Before creating your own dialog, be sure to check out the built-in dialogs. There might already be an implementation of the dialog you are looking for.

Creating a Dialog

A basic dialog with close button.

var plugin = new Dialog("Your Name", main.consumes, {
    name: "my-plugin-name",
    allowClose: true,
    title: "Some Title"
});

plugin.show();

Looks like this.

15701570

Dialog Properties

The following properties can be passed to the Dialog() constructor.

nameThe name of the plugin.
leftThe left position of the dialog in pixels.
topThe top position of the dialog in pixels.
widthThe width of the dialog in pixels.
titleThe title, displayed in the title bar of the dialog.
headingAn optional heading displayed in the body of the dialog.
bodyAn optional html string set as the body of the dialog.
modalWhether the user is prevented to interact with the application while the dialog is shown.
zindexThe zIndex of the dialog.
allowCloseWhether to show an x button and close on ESC.
elementsAn array of elements to show in the button bar
resizableWhether the dialog is resizable
classThe css class for the wizard dialog.

Adding your own contents

The easiest way to populate a dialog is by adding custom html and css. The following example loads css from dialog.css and adds a div element to the body of the dialog.

var plugin = new Dialog("Your Name", main.consumes, {
    name: "my-plugin-name",
    allowClose: true,
    title: "Some Title"
});

plugin.on("draw", function(e){
    // Insert css
    ui.insertCss(require("text!./dialog.css"), options.staticPrefix, plugin);

    // Set some custom HTML
    e.html.innerHTML = "<div class='myCSS'>Hello World</div>";
});

plugin.show();
15701570

Managing State during the Plugin's Life Time.

It important to note that the draw event only fires once during the life time of a dialog. To update the state of the dialog, use the show or hide events to manipulate the UI.

The following example shows a checkbox being reset when the form is shown.

var checkbox;

plugin.on("draw", function(e){
    e.html.innerHTML = "<label><input type='checkbox' name='example' /> Check me</label>";
    checkbox = e.html.querySelector("input");
});

plugin.on("show", function(e){
    checkbox.checked = false;
});
15701570

Combining a Dialog() with a Form()

For a complete guide on the Form() class check out the Form guide. Here, we'll create a simple authentication form to place in our dialog.

First we'll create the form in our drawing function.

authform = new Form({
    rowheight: 30,
    colwidth: 100,
    edge: "0 0 0 0",
    form: [
        {
            type: "image",
            src: options.staticPrefix + "/images/cloud9_logo.png",
            margin: "0 0 10px 0"
        },
        {
            title: "Username",
            name: "username",
            type: "textbox",
        },
        {
            title: "Password",
            name: "password",
            type: "password",
        },
        {
            name: "loginfail",
            type: "label",
            caption: "Could not login. Please try again.",
            style: "color:rgb(255, 143, 0);margin:5px 0 0 0px;"
        }
    ]
});

Then attach the form to the dialog.

var authform;
plugin.on("draw", function(e){
    authform = new Form({ ... });
    authform.attachTo(e.html);
});

Make sure to reset the form when the dialog shows:

plugin.on("show", function(){
    authform.reset();
});
15701570

In the following section we'll show how to add buttons to your form. The next code block shows a handler that could be called by a Login button.

function login(){
    if (!authform.validate())
        return handleInvalidForm();
    
    var json = authform.toJson();
    sendData(json);
}

Adding a button bar

You can configure a bar in the bottom of your dialog and configure it to display a set of form elements. The definition of the elements are the same as the definition of the Form() plugin. Only a subset of widgets are supported and unlike the Form() element, these widgets are stacked horizontally without labels.

The following widgets are supported:

  • checkbox
  • dropdown
  • textbox
  • button
  • label
  • image
  • divider
  • filler
  • custom

The following example creates a button bar with an OK button accompanied by a checkbox on the right, and a small dropdown on the left.

var plugin = new Dialog("Your Name", main.consumes, {
    title: "Example Buttons",
    allowClose : true,
    elements   : [
        { 
            type: "dropdown", 
            id: "items",
            width: 150,
            defaultValue: "example1",
            items: [
                { value: "example1", caption: "Example 1" },
                { value: "example2", caption: "Example 2" },
                { value: "example3", caption: "Example 3" }
            ]
        },
        { type: "filler" },
        { type: "checkbox", id: "all",  caption: "All my base" },
        { type: "button", id: "ok", color: "green", caption: "OK", "default": true }
    ]
}); 

plugin.show();

Which looks like this:

15701570

Make sure to reset the state of these form elements each time the form is displayed.

plugin.on("show", function(){
    plugin.update([
        { id: "items", items: [ ... ] }, // Update the items of the dropdown
        { id: "all", checked: false } // Set the checkbox to false
    ]);
});

In the same way toggle the visible attribute to hide and show elements.

Modal Dialogs

A modal dialog is a dialog that, while shown, prevents the user from interacting with the application in the background. In Cloud9 all modal dialogs show a semi-opaque layer on top of the rest of the UI to indicate that no interaction is possible.

Create a modal dialog by setting the modal property to true.

var plugin = new Dialog("Your Name", main.consumes, {
    name: "my-plugin-name",
    modal: true,
    title: "A Modal Dialog"
});

plugin.show();
15701570

Queued Dialogs

When you want to create a dialog to notify users of an event, you want to make sure no other dialog is shown at the same time. This is the case for several of the built-in dialogs, such as alert, confirm and question. To make sure your dialog interacts nicely with any of the other dialogs, instead of calling show(), call queue() instead. This will only display your dialog if no other queued dialog is shown.

The following is an example of a custom show method for your plugin.

function show(title, defaultChecked){
    plugin.queue(function(){
        plugin.title = title;
        checkbox.checked = defaultChecked;
    });
}

plugin.freezePublicAPI({
    /**
     * My custom show Method
     * @param ...
     */
    show: show
}

👍

Use the queue callback

Instead of setting the state of the dialog in the show event, set the state in the callback of the queue call. This is important because your dialog might be queued more than once!

A Full Example

The following code is the full implementation of the alert dialog. It uses most of the APIs discussed in this article.

define(function(require, module, exports) {
    main.consumes = ["Dialog", "util", "dialog.alert"];
    main.provides = ["dialog.alert"];
    return main;
    
    function main(options, imports, register) {
        var Dialog = imports.Dialog;
        var util = imports.util;
        
        /***** Initialization *****/
        
        var plugin = new Dialog("Ajax.org", main.consumes, {
            name: "dialog.alert",
            allowClose: true,
            modal: true,
            elements: [
                { type: "checkbox", id: "dontshow", caption: "Don't show again", visible: false },
                { type: "filler" },
                { type: "button", id: "ok", caption: "OK", "default": true, onclick: plugin.hide }
            ]
        });
        
        /***** Methods *****/
        
        function show(title, header, msg, onhide, options) {
            return plugin.queue(function(){
                if (header === undefined) {
                    plugin.title = "Notice";
                    header = title;
                    msg = msg || "";
                }
                else {
                    plugin.title = title;
                }
                plugin.heading = util.escapeXml(header);
                plugin.body = options && options.isHTML ? msg : (util.escapeXml(msg) || "")
                    .replace(/\n/g, "<br />")
                    .replace(/(https?:\/\/[^\s]*\b)/g, "<a href='$1' target='_blank'>$1</a>");
                
                plugin.update([
                    { id: "dontshow", visible: options && options.showDontShow }
                ]);
                
                plugin.once("hide", function(){
                    onhide && onhide();
                });
            });
        }
        
        /***** Register *****/
        
        /**
         *
         */
        plugin.freezePublicAPI({
            /**
             * @readonly
             */
            get dontShow(){ 
                return plugin.getElement("dontshow").value;
            },
            
            /**
             * Show an alert dialog.
             * 
             * @param {String} [title]     The title to display
             * @param {String} header      The header to display
             * @param {String} [msg]       The message to display
             * @param {Function} [onhide]  The function to call after it's closed.
             */
            show: show
        });
        
        register("", {
            "dialog.alert": plugin
        });
    }
});