A Customized ExtJS Toolbar

Posted on December 2nd, 2009 by Arthur Kay

The ExtJS grid is probably the most often used widget in the entire ExtJS library. The Ext.grid.GridPanel() object allows the developer to neatly display JSON or XML data returned from the server with little coding effort.

I’ve been working on an application for some time that necessitates changes to my grid’s toolbar depending upon several factors. The challenge that I’ve run into is that the default Ext.Toolbar() object is not very helpful when you try to show/hide options which are not specifically grouped.

For example, let’s say that you have a layout like the one pictured below. This particular layout allows the user to manage a list of physical locations and group them into categories.

ExtJS Toolbar Extension

As you can see, the grid has several top-level UI elements: a drop-down menu, a combo-box and several generic buttons. Our drop-down menu also has multiple options for the user to select (add/remove, etc).

This application requires that certain options are only visible when the grid is in its default (or ‘root’) view. Other options become visible (or hidden) when the grid is filtered by clicking on a category in the tree or by selecting a previously saved search algorithm. In other words, the toolbar’s functionality depends on some kind of state.

ExtJS Toolbar Extension

Now as far as I know, there isn’t a plugin or user extension available which meets the requirements my application needs. Therefore I created my own!

Override Toolbar Buttons/Actions

The first thing I needed to do was mark which toolbar options need to be hidden in specified states. I did this via a simple override statement on Ext.Component() and Ext.Action(). This was necessary because ExtJS toolbars can contain any Component() sub-class AND Ext.Action() instances which do not inherit from Component(). Thus I needed to cover both cases.

/**
 * Add markAsHidden member to all Components.
 * Used for marking toolbar items/buttons as hidden
 */
Ext.override(Ext.Component, {
    markAsHidden: []
});
Ext.override(Ext.Action, {
    markAsHidden: []
});

The new “markAsHidden” member  is an array (defaults to an empty array) which can be given any number of ’states’ in which the button or action must be hidden from the user.

You can now add these states via the button/action config:

var myButton = new Ext.Action({
    text: 'My Button',
    markAsHidden: [ 'someState', 'anotherState' ],
    handler: function() { ... }
});

Extend Ext.Toolbar()

My.Toolbar() is a basic extension of the Ext.Toolbar() object, with only two things which require explanation.

/**
 * @class My.Toolbar
 * @extends Ext.Toolbar
 * @constructor
 * @param {object} configObj
 * @cfg {array} items
 */
My.Toolbar = function(configObj) {
    var thisObject = this;

    /**
     * @method
     * @description Method to update the toolbar, showing/hiding specified
     *     buttons based on the passed display type.
     *     Common values are: 'root', 'child', 'query'
     * @param {string} displayType
     */
    this.updateDisplay = function(displayType) {
        function checkForHiddenFlag(toolbarItem) {
            if (toolbarItem.markAsHidden.indexOf(displayType) == -1) {
                toolbarItem.show();
            }
            else {
                toolbarItem.hide();
            }

            //cascade into the menu actions
            if (toolbarItem.isXType('button')) {
                if (toolbarItem.menu) {
                    toolbarItem.menu.items.each(checkForHiddenFlag);
                }
            }
        }

        thisObject.items.each(checkForHiddenFlag);
    };

    Ext.apply(this, {
        items: configObj.items
    });

    My.Toolbar.superclass.constructor.apply(this, arguments);

    this.mon(
        thisObject,
        'render',
        function(thisComponent) {
            thisComponent.updateDisplay('root');
        }
    );
};
Ext.extend(My.Toolbar, Ext.Toolbar, {});

First, I added an updateDisplay() method which (when called with a string parameter) will hide any toolbar options marked to-be-hidden in the specified state. It even goes into sub-menus to hide menu options!

Second, I run updateDisplay(‘root’) when the toolbar renders to put the grid into a default state.

So… now what?

The idea is that we can change the state of the toolbar whenever we need to – like on UI events such as tree-node clicks or a combo-box selection.

myTree.on(
    'click',
    function(theNode, theEvent) {
        myGrid.getTopToolbar().updateDisplay('someState');
    }
);

This extension is still a bit of a work in progress, but hopefully it helps a few of you ExtJS developers out there!

Share and Enjoy:
  • RSS
  • Facebook
  • StumbleUpon
  • Digg
  • Sphinn
  • del.icio.us
  • Technorati
  • Reddit
  • LinkedIn
  • Twitter
  • Yahoo! Buzz

Leave a Reply