Ext JS checkbox group, select just one or none

Ext JS checkbox group, select just one or none

Custom control Sencha Ext JS checkboxgroup select one or none (updated august 2018)

This post is an update on the original post of November of 2015. I just made an update on this small piece of code because I thought there was a bug in the new release of Sencha Ext JS version 6.6.0.

I saw that the original code didn't had this selection of "just one or none" was not a custom control. So I updated the code and now it is a control (Ext.ux.form.CheckboxOneOrNone). You can find the fiddle here: link

Ext.define('Ext.ux.form.CheckboxOneOrNone', {
    extend: 'Ext.form.CheckboxGroup',
    xtype: 'checkboxoneornone',
    items: [],
    chkBoxConfig: {},

    _selected: {
        value: null
    },

    defaults: {
        listeners: {
            scope: this,
            change: function (chkbox) {
                let value = null;
                let parent = chkbox.ownerCt;

                if (chkbox.checked) {
                    parent.resetBoxes(parent, chkbox.inputValue);
                    parent._selected.value = chkbox.inputValue;
                } else {
                    parent._selected.value = null;
                }

                value = parent._selected.value;

                parent.fireEvent('checkboxvaluechanged', parent, chkbox, value);
            }
        }
    },
    initComponent: function () {
        Ext.apply(this.defaults, this.chkBoxConfig);
        this.callParent();
    },
    resetBoxes: function (group, val) {
        let selecter = `checkbox[inputValue!=${val}]`;
        let boxes = group.query(selecter);
        Ext.each(boxes, function (box) {
            box.reset();
        });
    },
    getSelected: function () {
        return this._selected;
    },
    getCheckedValue: function() {
        let me = this;
        return me._selected['value'];
    }
});

How to use it?

var panel = Ext.create('Ext.form.Panel', {
    title: 'CheckboxGroup select one or none',
    margin: 20,
    width: 600,
    bodyPadding: 10,
    renderTo: Ext.getBody(),
    items: [{
        xtype: 'checkboxoneornone',
        layout: 'column',
        chkBoxConfig: {
            columnWidth: 0.5,
            padding: '0 20 0 0'
        },
        items: [{
            boxLabel: 'Netherlands',
            inputValue: 'Rotterdam'
        }, {
            boxLabel: 'Germany',
            inputValue: 'München'
        }, {
            boxLabel: 'Romania',
            inputValue: 'Timisoara'
        }, {
            boxLabel: 'Bulgaria',
            inputValue: 'Plovdiv'
        }],
        listeners: {
            checkboxvaluechanged: function(chkboxgroup, chkbox, value) {
                var panel = chkboxgroup.up('panel');
                var fld = panel.down('displayfield');
                fld.tpl.overwrite(fld.el, {
                    city: value !== null ? value : 'none'
                });
            }
        }
    }, {
        xtype: 'displayfield',
        itemId: 'city',
        tpl: new Ext.XTemplate('You have selected: {city}')
    }, {
        xtype: 'button',
        text: 'Selected value',
        handler: function(b) {
            var panel = b.up('panel');
            var selected = panel.down('checkboxoneornone').getSelected();
            alert(selected.value === null ? 'none' : selected.value);
        }
    }]
});

panel.show();

Original post of November 2015

This is just a small post with a tip how you can have in Ext JS (version 4.2 up to 6) an Ext.form.CheckboxGroup with the ability to select just one at the time, or none at all.

I needed this for a project I am working on and while I was searching on the internet I saw I wasn't the only one looking for something like this. Therefor I shared it with you.

The Sencha Fiddle to try it for yourself you can find here: link

Ext.application({
    name: 'Fiddle',

    launch: function() {

        function resetBoxes(group, val) {
            var selecter = 'checkbox[inputValue!=' + val + ']';
            var boxes = group.query(selecter);
            Ext.each(boxes, function(box) {
                box.reset();
            });
        }

        var panel = Ext.create('Ext.form.Panel', {
            title: 'CheckboxGroup select one or none',
            height: 150,
            margin: 20,
            width: 500,
            bodyPadding: 10,
            renderTo: Ext.getBody(),
            items: [{
                xtype: 'checkboxgroup',
                name: 'chk_group',
                columnWidth: .25,
                defaults: {
                    name: 'chk_group',
                    listeners: {
                        scope: this,
                        change: function(chkbox) {
                            if (chkbox.checked) {
                                resetBoxes(chkbox.ownerCt, chkbox.inputValue);
                            }
                            /* not relevant for the understanding of the sample */
                            var panel = chkbox.ownerCt.ownerCt;
                            var f = panel.down('displayfield');
                            f.tpl.overwrite(f.el, {
                                i: chkbox.checked ? chkbox.inputValue : 'none'
                            });
                            /* so you can delete this, with the displayfield too */

                        }
                    }
                },
                items: [{
                    boxLabel: 'Netherlands',
                    inputValue: 'Rotterdam'
                }, {
                    boxLabel: 'Germany',
                    inputValue: 'München'
                }, {
                    boxLabel: 'Romania',
                    inputValue: 'Timisoara'
                }, {
                    boxLabel: 'Bulgaria',
                    inputValue: 'Plovdiv'
                }]
            }, {
                /* not relevant to the sample */
                xtype: 'displayfield',
                tpl: new Ext.XTemplate('You have selected: {i}')
            }]
        });

        panel.show();
    }
});