wck555
7 Nov 2007, 5:59 AM
If you setup a ComboBox like this:
combo = new Ext.form.ComboBox({
fieldLabel: 'Class',
hiddenName: 'MEClassID', // name of field bound to this control
displayField: 'text',
valueField: 'id',
width:100,
mode:'local',
typeAhead:true,
triggerAction:'all',
selectOnFocus: true,
forceSelection: true,
store: new Ext.data.SimpleStore({ fields: ['id', 'text'], data: meClassLookup })
}));
you get a ComboBox that displays 'text' values to the user while storing 'id' values behind the scenes. If you call setValue(id), the ComboBox displays the 'text' value from the data store associated with that 'id'. If the user types into the ComboBox, the data store items are filtered to match what the user is typing and displayed to the user in a pop-down list. When the user chooses an item, the 'text' value is displayed and the 'id' value is stored. Cool :)
The problem arises if you call setValue() (or load form data or do anything else that causes Ext to call setValue() behind the scenes) after the user has selected an item in the ComboBox by typing. The filter applied to the data store while the user was typing still remains. When setValue() is called, the ComboBox searches the data store looking for a matching 'id' and then displays the associated 'text' value. However the data store is still filtered. So if the 'text' value associated with the new 'id' doesn't match the filter (i.e. doesn't match what the user typed into the ComboBox), the ComboBox will fail to find the 'text' value to match the new 'id' and will fallback to displaying the 'id' value instead.
There is a fairly straightforward workaround for now. You have to subclass the ComboBox class like this (I also added a few default values to match my needs, but these are optional)
Ext.form.LocalComboBox = Ext.extend(Ext.form.ComboBox, {
mode:'local',
typeAhead:true,
triggerAction:'all',
selectOnFocus: true,
forceSelection: false,
setValue: function(v)
{
// --- When user types a value into a combobox Ext creates a filter on the
// --- data store attached to the combobox to filter the values displayed to the user.
// --- Later, if setValue() is called, this filter is still set in the data store and
// --- the combo box may not display the text associated with the value.
// --- To work around this, clear the data store filter
this.store.clearFilter();
// --- Then call base class setValue() function
Ext.form.LocalComboBox.superclass.setValue.call(this, v);
}
});
Then use LocalComboBox whenever you need a ComboBox with a local data store
combo = new Ext.form.LocalComboBox({
fieldLabel: 'Class',
hiddenName: 'MEClassID', // name of field bound to this control
displayField: 'text',
valueField: 'id',
width:100,
forceSelection: true,
store: new Ext.data.SimpleStore({ fields: ['id', 'text'], data: meClassLookup })
}));
combo = new Ext.form.ComboBox({
fieldLabel: 'Class',
hiddenName: 'MEClassID', // name of field bound to this control
displayField: 'text',
valueField: 'id',
width:100,
mode:'local',
typeAhead:true,
triggerAction:'all',
selectOnFocus: true,
forceSelection: true,
store: new Ext.data.SimpleStore({ fields: ['id', 'text'], data: meClassLookup })
}));
you get a ComboBox that displays 'text' values to the user while storing 'id' values behind the scenes. If you call setValue(id), the ComboBox displays the 'text' value from the data store associated with that 'id'. If the user types into the ComboBox, the data store items are filtered to match what the user is typing and displayed to the user in a pop-down list. When the user chooses an item, the 'text' value is displayed and the 'id' value is stored. Cool :)
The problem arises if you call setValue() (or load form data or do anything else that causes Ext to call setValue() behind the scenes) after the user has selected an item in the ComboBox by typing. The filter applied to the data store while the user was typing still remains. When setValue() is called, the ComboBox searches the data store looking for a matching 'id' and then displays the associated 'text' value. However the data store is still filtered. So if the 'text' value associated with the new 'id' doesn't match the filter (i.e. doesn't match what the user typed into the ComboBox), the ComboBox will fail to find the 'text' value to match the new 'id' and will fallback to displaying the 'id' value instead.
There is a fairly straightforward workaround for now. You have to subclass the ComboBox class like this (I also added a few default values to match my needs, but these are optional)
Ext.form.LocalComboBox = Ext.extend(Ext.form.ComboBox, {
mode:'local',
typeAhead:true,
triggerAction:'all',
selectOnFocus: true,
forceSelection: false,
setValue: function(v)
{
// --- When user types a value into a combobox Ext creates a filter on the
// --- data store attached to the combobox to filter the values displayed to the user.
// --- Later, if setValue() is called, this filter is still set in the data store and
// --- the combo box may not display the text associated with the value.
// --- To work around this, clear the data store filter
this.store.clearFilter();
// --- Then call base class setValue() function
Ext.form.LocalComboBox.superclass.setValue.call(this, v);
}
});
Then use LocalComboBox whenever you need a ComboBox with a local data store
combo = new Ext.form.LocalComboBox({
fieldLabel: 'Class',
hiddenName: 'MEClassID', // name of field bound to this control
displayField: 'text',
valueField: 'id',
width:100,
forceSelection: true,
store: new Ext.data.SimpleStore({ fields: ['id', 'text'], data: meClassLookup })
}));