Linked Combo Plugin Working
Animal,
I've been distracted getting my code upgraded to Ext 4, but finally got back to this thing. I took your advice and implemented it as a plugin. I'd like to get some feedback from you on it, including any improvements or alternate approaches you might suggest.
- I used the store.filter() method, but would it be better to do something with the combo's beforequery event? I tried briefly and failed.
- There seems to be a problem where the first click 'stutters' and the combo closes up again. The second click works fine and shows the filtered list.
- I don't know what you mean by 'CQ' (oh crap, I think I just figured it out while typing. Did you mean combo query?! Dang, I knew that would have been better, but I couldn't get it working).
First, the plugin itself:
PHP Code:
Ext.define('IDB.selectbox.LinkedComboPlugin', {
extend: 'Ext.AbstractPlugin',
alias: 'plugin.linkedcombo',
/*
Must pass object like
{
comboId : 'myLinkedCombo',
thisField : 'thisField',
thatField : 'thatField'
}
*/
linkedCombo : undefined,
init : function(combo) {
combo.on('afterrender', this.onComboRender, this);
},
onComboRender : function(combo) {
var lc = Ext.ComponentQuery.query('#'+this.linkedCombo.comboId)[0];
//Watch to see when the linked combo changes, then clear this combo's value and fire the 'select' event
//so that a series of these will all clear themselves.
combo.mon(lc, 'select', function() {
combo.clearValue();
combo.fireEvent('select');
}, this);
//I think I could filter the options somehow with the beforequery event, but a minor attempt failed.
combo.on('beforequery', function(e) {
}, this);
//When this combo is expanded, stop and filter the store first based on the linked combo's selected record.
combo.on('expand', function(picker) {
var record = lc.idbGetRecord();
if(record) {
var thatValue = record.get(this.linkedCombo.thatField);
combo.store.clearFilter();
combo.store.filter([{
property : this.linkedCombo.thisField,
value : thatValue,
exactMatch : true
}]);
}
}, this);
}
});
Intended Usage:
PHP Code:
items : [{
fieldLabel: 'Datacenter',
xtype : 'IDB.selectbox.Site',
name : 'site_code',
itemId : 'siteCombo'
},{
fieldLabel: 'Cage',
xtype : 'IDB.selectbox.Cage',
name : 'cage',
itemId : 'cageCombo',
plugins : [
{
ptype: 'linkedcombo',
linkedCombo : {
comboId : 'siteCombo',
thisField : 'site_code',
thatField : 'site_code'
}
}
]
},{
fieldLabel: 'Row',
xtype : 'IDB.selectbox.Row',
name : 'row',
itemId : 'rowCombo',
plugins : [
{
ptype: 'linkedcombo',
linkedCombo : {
comboId : 'cageCombo',
thisField : 'cage_id',
thatField : 'id'
}
}
]
},{
fieldLabel: 'Rack',
xtype : 'IDB.selectbox.Rack',
name : 'rack',
itemId : 'rackCombo',
plugins : [
{
ptype: 'linkedcombo',
linkedCombo : {
comboId : 'rowCombo',
thisField : 'row_id',
thatField : 'id'
}
}
]
}]
Ext.form.ComboBox extention:
PHP Code:
Ext.define('IDB.selectbox.SelectBox', {
extend : 'Ext.form.ComboBox',
alias : 'widget.IDB.selectbox.SelectBox',
idbGetRecord : function() {
return this.store.findRecord(this.valueField, this.getValue(), 0, false, true, true);
},
initComponent : function() {
Ext.apply(this, {
triggerAction: 'all',
lastQuery: ''
});
this.callParent(arguments);
}
});
I can imagine other people wanting to use this, so anything I can do to further generalize it would be good too.
I also think my idbGetRecord function on the ComboBox ought to be added to the main line.