GUIWidgets

GUIWidget is the base class for everything in bbq that has a visual representation and as such is a class that you will become well acquainted with.

A simple class that extends GUIWidget is shown below:


include(bbq.gui.GUIWidget);

com.myapp.gui.MyWidget = new Class.create(bbq.gui.GUIWidget, {
    initialize: function($super) {
        $super();

        this.setRootNode("p");
        this.addClass("MyWidget");
    },

    render: function($super) {
        this.empty();

        this.appendChild("hello world");
    }
});

To add an instance of the class to a page, you'd do the following:


include(bbq.page.Page);
include(com.myapp.gui.MyWidget);

com.myapp.page.Home = new Class.create(bbq.page.Page, {
    initialize: function($super) {
        $super();

        var widget = new com.myapp.gui.MyWidget();
        widget.appendTo(document.body);
    }
});

This results in the following being added to the body tag of the document:

<p class="MyWidget">hello world</p>

Root node

Each GUIWidget has a root node. By default it's a div tag, but this behaviour can be overridden by calling the GUIWidget#setRootNode) method and passing in the name of the tag you'd like to have set:


include(bbq.gui.GUIWidget);

com.myapp.gui.MyWidget = new Class.create(bbq.gui.GUIWidget, {
    initialize: function($super) {
        $super();

        // sets the root node to a paragraph tag
        this.setRootNode("p");

        // sets the root node to an article
        this.setRootNode("article");
    }
});

appendTo/appendChild

A GUIWidget is a JavaScript Object, whereas the output of document.createElement is a Node. A very important distinction here is that the GUIWidget wraps a Node, so we can write code to add one GUIWidget to another, or even a Node to a GUIWidget, but we cannot add a GUIWidget to a node.

So, for example:


var widget = new com.myapp.gui.MyWidget();
var node = document.createElement("p");

// will not work
node.appendChild(widget);

Instead, we must use appendTo:


var widget = new com.myapp.gui.MyWidget();
var node = document.createElement("p");

// will work
widget.appendTo(node);

We can freely add objects of both types to widgets, however:


var parentWidget = new com.myapp.gui.MyWidget();
var childWidget = new com.myapp.gui.MyWidget();
var node = document.createElement("p");

// add a Node
parentWidget.appendChild(node);

// add a GUIWidget
parentWidget.appendChild(childWidget);

It would be nice if we could override Node#appendChild to detect GUIWidgets and act accordingly but the security model of most browsers prevents this.

Render

The render method is the point at which your GUIWidget should add and child widgets to it's root node. It's likely to get call several times during the life of the widget, so it's recommended to first call empty to insure you don't end up with more child nodes than you expected.

Render may be called before your GUIWidget has been added to the DOM so please do not assume the existence of anything else on the page, or even that your root node has a parentNode.


include(bbq.gui.GUIWidget);
include(bbq.gui.button.Button);
include(bbq.util.Log);

com.myapp.gui.MyWidget = new Class.create(bbq.gui.GUIWidget, {
    initialize: function($super) {
        $super();
    },

    render: function() {
        // removes all existing child nodes
        this.empty();

        // Adds a paragraph tag with the text "Hello world!"
        this.appendChild(DOMUtil.createElement("p", "Hello world!"));

        // Adds a clickable button
        this.appendChild(new bbq.gui.button.Button({
            text: "Click me",
            onClick: this._buttonClicked.bind(this)
        }));
    },

    _buttonClicked: function() {
        Log.info("The button was clicked!");
    }
});

See the JSDocs for more information.

Root node manipulation

Several methods operate on the root node, some common ones are listed below, but for the full list, please see the JSDocs.

addClass

GUIWidget#addClass adds a CSS class to the root node:


var widget = new com.myapp.gui.MyWidget();
widget.addClass("foo");

This will result in the following HTML:

<div class="foo"></div>

removeClass

GUIWidget#removeClass removes a CSS class to the root node:


var widget = new com.myapp.gui.MyWidget();
widget.addClass("foo");
widget.addClass("bar");

widget.removeClass("foo");

This will result in the following HTML:

<div class="bar"></div>

hasClass

GUIWidget#hasClass returns true if the root node has the passed CSS class:


var widget = new com.myapp.gui.MyWidget();
widget.addClass("foo");

// false
widget.hasClass("bar");

// true
widget.hasClass("foo");

This will result in the following HTML:

<div class="bar"></div>

setStyle/getStyle

GUIWidget#setStyle sets a CSS style on the root node and GUIWidget#getStyle) returns it:


var widget = new com.myapp.gui.MyWidget();
widget.setStyle("position", "absolute");

// returns "absolute"
widget.getStyle("position");

This will result in the following HTML:

<div style="position: absolute"></div>

To remove a class, pass in null:


var widget = new com.myapp.gui.MyWidget();
widget.setStyle("position", null);

// returns null
widget.getStyle("position");