How to add Save and Cancel buttons to a Sencha ExtJS container (panel, window)

To add Save and Cancel buttons to a Sencha ExtJS form or panel, use the following code:

dockedItems: [
    {
        xtype: 'toolbar',
        flex: 1,
        dock: 'bottom',
        ui: 'footer',
        layout: {
            pack: 'end',
            type: 'hbox'
        },
        items: [
            {
                xtype: 'button',
                text: 'Cancel',
                itemId: 'cancel',
                iconCls: 'cancel'
            },
            {
                xtype: 'button',
                text: 'Save',
                itemId: 'save',
                iconCls: 'save'
            }
        ]
    }
]

That code adds the buttons to a Sencha toolbar that’s docked at the bottom of the container it’s used in. As you can see, the code is clean and easily reusable (via copy and paste).

I know that this code works in Sencha ExtJS, and it probably works in Sencha Touch as well.

A complete example

If it helps to see how that code is used in a complete example, here’s the source code for a form that’s implemented as a Sencha ExtJS Window:

Ext.define('Finance.view.TransactionForm', {
    extend: 'Ext.window.Window',
    alias: 'widget.transactionform',

    height: 200,
    width: 550,

    layout: {
        align: 'stretch',
        type: 'vbox'
    },

    title: 'Transaction',

    items: [
        {
            xtype: 'form',
            bodyPadding: 5,
            layout: {
                type: 'vbox',
                align: 'stretch'
            },
            defaults: {
                anchor: '100%',
                xtype: 'textfield',
                blankText: 'This is required',
                labelWidth: 90
            },
            items: [
                // TODO do i need this hidden field?
                {
                    xtype: 'hiddenfield',
                    fieldLabel: 'Label',
                    name: 'id'
                },
                // symbol, type, price, qty, datetime, notes
                {
                    fieldLabel: 'Symbol',
                    name: 'symbol',
                    itemId: 'symbol',
                    allowBlank: false,
                    maxLength: 10,
                    maskRe: /([a-zA-Z0-9]+)$/   // only allow letters and numbers, no spaces
                },
                {
                    fieldLabel: 'Type (B/S)',
                    name: 'ttype',
                    itemId: 'ttype',
                    allowBlank: false,
                    maxLength: 1       //TODO convert this field to a radio button
                },
                {
                    fieldLabel: 'Price',
                    name: 'price',
                    itemId: 'price',
                    allowBlank: false,  //TODO add a regex here to validate a double
                    maxLength: 10
                },
                {
                    fieldLabel: 'Qty',
                    name: 'quantity',
                    itemId: 'quantity',
                    allowBlank: false,
                    maxLength: 10,
                    maskRe: /([0-9]+)$/   // int field
                },
                {
                    // TODO is this needed?
                    xtype: 'hiddenfield',
                    fieldLabel: 'datetime',
                    name: 'datetime'
                },
                {
                    fieldLabel: 'Notes',
                    xtype: 'textareafield',
                    name: 'notes',
                    itemId: 'notes',
                    allowBlank: true
                },
            ]
        }
    ],

    dockedItems: [
        {
            xtype: 'toolbar',
            flex: 1,
            dock: 'bottom',
            ui: 'footer',
            layout: {
                pack: 'end',
                type: 'hbox'
            },
            items: [
                {
                    xtype: 'button',
                    text: 'Cancel',
                    itemId: 'cancel',
                    iconCls: 'cancel'
                },
                {
                    xtype: 'button',
                    text: 'Save',
                    itemId: 'save',
                    iconCls: 'save'
                }
            ]
        }
    ]

});

This code comes from my Finance-DesktopClient project.