A Customized ExtJS Toolbar

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!

About 

With nearly 20 years of software engineering and operations experience, Arthur Kay offers an extraordinary set of leadership skills and technical expertise to develop meaningful products and high-performing teams. He has worked with Fortune 500 companies, VC-funded startups and companies across a wide variety of industries to build cutting-edge software solutions.

Arthur is a successful entrepreneur, technology professional, and mentor. He is a full-time family man, part-time consultant and spare-time musician. He graduated from Loyola University Chicago and currently lives in greater Chicago-land.

Leave a Reply

Your email address will not be published. Required fields are marked *