PDA

View Full Version : [FIXED] Resetting the editable combobox to non empty original value results in empty val



Qtx
26 Jun 2011, 12:35 PM
REQUIRED INFORMATION


Ext version tested:

Ext 4.0.2


Browser versions tested against:

IE 9.0.8112.16421
FF 5, firebug 1.7.3
Opera 11.11
Chrome 12.0.742.100
Safari 5.0.5


Description:

If a editable combobox has a non-empty initial value, resetting it results in the empty value instead of the initial value.
This happens only by one condition - only when you typed something in the field before resetting.


Steps to reproduce the problem:

I adjusted the example form/field-types.html. I added the editable combobox with items (Germany, France, Russia) and a button that resets it.
The initial value is Germany
Type the value 'USA' in the combobox field
Push the button 'Reset' and you will see, that the value is set to empty instead of setting to 'Germany'


The result that was expected:

The combobox should be reset to its initial value.


The result that occurs instead:

The combobox is reset to empty value.


Test Case:

adjusted forms/field-types.js



Ext.require([
'Ext.form.*'
]);

Ext.onReady(function() {

var countries = [
['DE', 'Germany'],
['RU', 'Russia'],
['FR', 'France']
];

var formPanel = Ext.create('Ext.form.Panel', {
frame: true,
title: 'Form Fields',
width: 340,
bodyPadding: 5,

fieldDefaults: {
labelAlign: 'left',
labelWidth: 90,
anchor: '100%'
},

items: [
{
xtype: 'combo',
fieldLabel: 'Country',
id: 'country',
name: 'country',
store: countries,
value: 'DE',

triggerAction: 'all',
forceSelection: false,
editable: true,
typeAhead: true,
selectOnFocus: true
},{
xtype: 'textfield',
name: 'textfield1',
fieldLabel: 'Text field',
value: 'Text field value'
}, {
xtype: 'textfield',
name: 'password1',
inputType: 'password',
fieldLabel: 'Password field'
}, {
xtype: 'filefield',
name: 'file1',
fieldLabel: 'File upload'
}, {
xtype: 'textareafield',
name: 'textarea1',
fieldLabel: 'TextArea',
value: 'Textarea value'
}, {
xtype: 'displayfield',
name: 'displayfield1',
fieldLabel: 'Display field',
value: 'Display field <span style="color:green;">value</span>'
}, {
xtype: 'numberfield',
name: 'numberfield1',
fieldLabel: 'Number field',
value: 5,
minValue: 0,
maxValue: 50
}, {
xtype: 'checkboxfield',
name: 'checkbox1',
fieldLabel: 'Checkbox',
boxLabel: 'box label'
}, {
xtype: 'radiofield',
name: 'radio1',
value: 'radiovalue1',
fieldLabel: 'Radio buttons',
boxLabel: 'radio 1'
}, {
xtype: 'radiofield',
name: 'radio1',
value: 'radiovalue2',
fieldLabel: '',
labelSeparator: '',
hideEmptyLabel: false,
boxLabel: 'radio 2'
}, {
xtype: 'datefield',
name: 'date1',
fieldLabel: 'Date Field'
}, {
xtype: 'timefield',
name: 'time1',
fieldLabel: 'Time Field',
minValue: '1:30 AM',
maxValue: '9:15 PM'
}],

buttons: [
{
text: 'Set',
handler: function () {
var f = formPanel.getForm().findField('country');

f.setValue('USA');
}
},
{
text: 'Reset',
handler: function () { formPanel.getForm().reset(); }
}
]

});

formPanel.render('form-ct');

});



HELPFUL INFORMATION


See this URL for live test case: http://www.apfelsine.ru/ext402/examp...ld-types2.html


Possible fix:

The fact that this occurs only if you have typed something before implies filtering issues.
When setting the combobox value, you are looking in the store for it.
If you typed something before, the store is FILTERED due to 'typeahead'! Therefore the value is not found, although this value exists in the store.
The filter should be removed from the store before looking for the value, in the method ComboBox.setValue



Ext.override(Ext.form.field.ComboBox, {

setValue: function(value, doSelect) {
var me = this,
valueNotFoundText = me.valueNotFoundText,
inputEl = me.inputEl,
i, len, record,
models = [],
displayTplData = [],
processedValue = [];

if (me.store.loading) {
// Called while the Store is loading. Ensure it is processed by the onLoad method.
me.value = value;
return me;
}

// This method processes multi-values, so ensure value is an array.
value = Ext.Array.from(value);

// Loop through values
for (i = 0, len = value.length; i < len; i++) {
record = value[i];
if (!record || !record.isModel) {
this.store.clearFilter(false);
record = me.findRecordByValue(record);
}
// record found, select it.
if (record) {
models.push(record);
displayTplData.push(record.data);
processedValue.push(record.get(me.valueField));
}
// record was not found, this could happen because
// store is not loaded or they set a value not in the store
else {
// if valueNotFoundText is defined, display it, otherwise display nothing for this value
if (Ext.isDefined(valueNotFoundText)) {
displayTplData.push(valueNotFoundText);
}
displayTplData.push(value[i]);
processedValue.push(value[i]);
}
}

// Set the value of this field. If we are multiselecting, then that is an array.
me.value = me.multiSelect ? processedValue : processedValue[0];
if (!Ext.isDefined(me.value)) {
me.value = null;
}
me.displayTplData = displayTplData; //store for getDisplayValue method
me.lastSelection = me.valueModels = models;

if (inputEl && me.emptyText && !Ext.isEmpty(value)) {
inputEl.removeCls(me.emptyCls);
}

// Calculate raw value from the collection of Model data
me.setRawValue(me.getDisplayValue());
me.checkChange();

if (doSelect !== false) {
me.syncSelection();
}
me.applyEmptyText();

return me;
}

});
Additional CSS used:

only default ext-all.css


Operating System:

Windows 7

edspencer
27 Jun 2011, 1:37 PM
Thanks - verified and pushed to the bug tracker

Qtx
22 Oct 2011, 9:45 AM
I have got the version 4.0.7 and checked the combobox issues. Almost all of them are fixed in 4.0.7 and now it works like it was in ExtJS 3.x. One problem remains however.

Once, you typed a value that is not in the combobox store, the combobox store remains filtered. If later a setValue is called, it might work wrong because of the following reason. It is tried to find the value in the Combobox Store

record = me.findRecordByValue(record);

And the value might not be found even if it is in the store. Why? Because the Store remains filtered. Thus, it is very important to call

this.store.clearFilter(false);

before doing

record = me.findRecordByValue(record);

Filtering is necessary for typing ahead, but the search of the value to be set should occur over the whole store and not over the filtered.