PDA

View Full Version : [DEFER] Combobox multiple inputs



merovius
2 Jun 2010, 7:49 AM
Hello guys,

I've some troubles with an auto completable Combobox.

The combobox is loaded by a store.

This store has 2 fields :
- myId, which is unique (=> valueField in the ComboBox)
- myText, which may be duplicated (=> displayField in the ComboBox)

Ex :
the store contains 2 entries :
myId | myText
_____________
1 | text 1
2 | text 1

When I choose the second entry, (with myId == 2) and then look at the valueField of my ComboBox, the result is 1 instead of 2 (but in Ext 2.2.1, the result was 2).

I investigated into the ext-all-debug source and I found these pieces of code :

The beforeBlur function has been overridden in ComboBox (it was emptyFn in Ext 2.2.1)


beforeBlur : function(){
this.assertValue();
}
Here is the assertValue method for the ComboBox objects :


// private
assertValue : function(){
[1]
var val = this.getRawValue(),
rec = this.findRecord(this.displayField, val);

if(!rec && this.forceSelection){
if(val.length > 0 && val != this.emptyText){
this.el.dom.value = Ext.value(this.lastSelectionText, '');
this.applyEmptyText();
}else{
this.clearValue();
}
}else{
if(rec){
// onSelect may have already set the value and by doing so
// set the display field properly. Let's not wipe out the
// valueField here by just sending the displayField.
[2]
if (val == rec.get(this.displayField) && this.value == rec.get(this.valueField)){
return;
}
val = rec.get(this.valueField || this.displayField);
}
[3]
this.setValue(val);
}
}
The beforeBlur function is called in this Ext.form.Field function :


onBlur : function(){
this.beforeBlur();
if(this.focusClass){
this.el.removeClass(this.focusClass);
}
this.hasFocus = false;
if(this.validationEvent !== false && (this.validateOnBlur || this.validationEvent == 'blur')){
this.validate();
}
var v = this.getValue();
if(String(v) !== String(this.startValue)){
this.fireEvent('change', this, v, this.startValue);
}
this.fireEvent('blur', this);
this.postBlur();
}
Just take a look in the assertValue function and you will see that the ComboBox valueField may be changed after a selection.

~

We choose the second entry (with myId = 2).

[1]
We search in the combobox' store the first occurence of this.getRawValue()
aka the displayed text of our combobox (which is the same for the 2 entries of the store).

[2]
If we get a record from this search, we verifiy if the valueField of the record and the combobox are equals.

In our case :
- the record returned by the search is {myId = 1, myText = text 1}
- combobox.valueField = 2, combobox = text 1

[3]
Because 1 is not equal to 2, we set the valueField of our combobox to ... 1 instead of being unchanged.

~

I post this issue in the bug section but perhaps is it an implementation choice (or my mistake of course :) ).

But for me there is more logic to do the search defined in [1] first by the valueField (which is unique in our case) and then (if valueField doesn't exist) by the displayField.

Why don't we have the possibility to choose the field used by the search in [1] (valueField or displayField) ?

What's the utility of the parameter autoSelect if only the first row of the store is selected when there are 2 rows with the same displayField ?

Because in my case, I had to override the beforeBlur function to avoid the call of the assertValue. function.

Jamie Avins
2 Jun 2010, 8:42 AM
I agree there needs to be a logic cleanup in combo (among other things there). At this point it's going to require an implementation which may break some existing code and as such we're looking to rewrite much of the internals for Combo in 4.x.