Ext JS checkbox group, select just one or none
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();
}
});