PDA

View Full Version : forceselection: false and valuefield



Tim Toady
2 Aug 2010, 6:46 AM
So I have a combo that I want the user to be able to type in data if it is not present in the list. If it is in the list I would like it to use the id of the item. If I have forceSelection: false and valueField: 'id', text not in the list gets automatically deleted on blur. If there is no valuefield, the displayField/typed in text gets sent.

It makes sense to me that if valuefield is set that the combo would be made blank on blur if text not in the list is entered. But how can I allow it to be entered and send it as the value and have the selections send their IDs?

Thanks. Sorry if I didn't ask the question well. I am not sure how else to phrase it.

Condor
2 Aug 2010, 7:48 AM
Create the combobox with a name (no hiddenName) and without a valueField. Next, create a hidden field that will hold the id.

In the change event of the combobox, find the record in the store and update the value of the hidden field with either the id of the record (if found) or blank (if not found).

Tim Toady
2 Aug 2010, 10:48 AM
Ah. That sounds like a reasonable solution. Thanks

Tim Toady
5 Aug 2010, 10:49 AM
I just went to implement it now and ran into an issue. The displayfield is not necessarily unique. So the change event only fires when something completely different is selected. Select will give me the record, but it doesn't fire when something is typed in. In that case I could use change, but then it might overwrite what select put in there because it would find the first record with that value for the displayfield.

Condor
5 Aug 2010, 12:10 PM
First try if the selectedRecord has the current displayValue, if it doesn't then do the findRecord.

Tim Toady
5 Aug 2010, 1:24 PM
It looks like its working. Not 100% sure, but I think its right.



listeners: {
select: function(combo, rec, index) {
this.nextSibling().setValue(rec.data.id);
},
change: function(combo, newValue, oldValue){
sibRec = this.store.getAt(this.store.find('id', this.nextSibling().getValue()));
if (sibRec === undefined) { //the hidden field does not contain an ID
rec = this.store.getAt(this.store.find('location', newValue)); //Is there a value that matches the value typed in?
if (rec === undefined) {
this.nextSibling().setValue(''); //Clear the id since the data was typed in
} else {
this.nextSibling().setValue(rec.data.id); //Insert the id of the first matching record
}
} else {
if (sibRec.data.location != newValue) {
this.nextSibling().setValue('');
}
}
}
}

Condor
5 Aug 2010, 10:27 PM
Your code doesn't work correctly if you select an item the second time. I would recommend:

change: function(combo, newValue, oldValue){
var hidden = this.nextSibling(),
record = this.store.getAt(this.store.findExact('id', hidden.getValue()));
if (!record || record.get('location') != newValue) {
record = this.store.getAt(this.store.findExact('location', newValue));
hidden.setValue(record ? record.get('id') : '');
}
}

Tim Toady
9 Aug 2010, 4:59 AM
Thank you for the help. I am very impressed with the readability of your code. Mine looks totally garbled in comparison. I used yours only changing findExact to find because I think I would prefer a case insensitive search.