I'm using ExtJS 4 and looking for a way I can hide currently selected value from combo's dropdown list?
So instead of this ("Alaska" currently selected in combobox):
I want the list of values look like this:
In my case the combobox is not editable (i.e. you can't input an arbitrary value), I don't think it makes much sense to display the selected value two times: once in the input field and once in the dropdown list. I already see what is selected, I want the dropdown list to only show me other options I can select.
So far I don't see an easy way to do it. Probably the best place to start at is filtering combobox store but combobox uses its own filters for live search functionality.
Anybody considered this problem? Am I trying to do something weird? I'm surprised that I haven't been able to find any related topics.
I don't think you have to much options here... maybe you could do something like this:
Ext.define('Your.company.Combo', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.specialcombo',
/**
* @cfg {boolean} hideActive
* True to hide any selected record. Defaults to <tt>true</tt>.
*/
hideActive: true,
/**
* @private {Ext.data.Model[]} hideActive
* A Array of selected records.
*/
initComponent: function () {
this.selectedRecords = [];
this.callParent(arguments);
this.on('select', this.onSelectionChange, this);
},
/**
* @private onChangeSelection
* eventhandler selections
*/
onSelectionChange: function (me, recs) {
if(!me.hideActive)
return;
// write the current selected back to the store (you need to suspend autoSync if active)
me.store.add(me.selectedRecords);
// set the selected as new recordlist
me.selectedRecords = recs;
// remove the selected from the store
me.store.remove(recs);
}
});
That example is totally untested. But as the store is mainly bound to the BoundList which is not direct connected to the textfield this should work. You are doing a sort of caching here.
I ended up using a modified version of @sra's solution:
Ext.define('My.ComboBox', {
extend: 'Ext.form.field.ComboBox',
/**
* @cfg {Boolean} hideActive=true
* When true, hides the currently selected value from the dropdown list
*/
hideActive: true,
/**
* @private {Ext.data.Model[]} selectedRecords
* A Array of selected records, used when hideActive is true
*/
initComponent: function() {
this.selectedRecords = [];
this.callParent();
},
setValue: function(value, doSelect) {
var store = this.store;
if(this.hideActive) {
store.suspendEvents(false);
// write the current selected back to the store (you need to suspend autoSync if active)
// do this BEFORE callParent so the currently selected record would be found in the store
store.add(this.selectedRecords);
}
this.callParent(arguments);
if(this.hideActive) {
// set the selected as new recordlist
this.selectedRecords = this.valueModels;
// remove the selected from the store
store.remove(this.valueModels);
store.resumeEvents();
store.fireEvent('refresh', store);
}
return this;
}
});
The 'hiding' logic is the same, only I perform it in the setValue
method to make sure that it also works when programmatically setting combo's value, including the case where the combobox is initialized with a value.
UPD Also, looks like store.add(this.selectedRecords);
has to be called before this.callParent(arguments);
, otherwise combobox will act weird if we attempt to set the same value twice (it simply wouldn't find the active record in the store cause we removed it, so it'll reset to blank).
I suspend store's events to prevent some quirks caused by combobox trying to synchronize with its dropdown list in the middle of my manipulations with selected record(s) and manually trigger store's 'refresh'
event when I'm done so the list gets eventually updated. This may have performance impact but so far I don't know a better solution.
ExtJS 3 I wrote this answer based on the others. Works great for me, its a little modified from what your looking for though.
Name.space.name = new Ext.extend(Ext.form.ComboBox, {
type: 'all',
oldrec: null,
store: null,
constructor: function (config) {
var me = this;
if (config.type === 'all') {
me.store = AllConditionStore;
} else {
me.store = ?.?('RuleParameterType');
}
config = Ext.apply({
store: me.store,
valueField: 'id',
hideActive: true,
triggerAction: 'all',
lazyRender: true,
allowBlank: false,
mode: 'local',
displayField: 'text',
listeners: {
select: function (me, recs, index) {
if (me.oldrec !== null)
me.store.add(me.oldrec);
me.oldrec = recs;
// remove the selected from the store
me.store.remove(recs);
// redo store
}
}
}, config);
?.?.Parameter.superclass.constructor.call(this, config);
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With