You found a bug! We've classified it as
EXTJS-3298
.
We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
-
Ext JS Premium Member
[4.0.2] combobox setValue doesn't as expected
REQUIRED INFORMATION
Ext version tested:
Browser versions tested against:
- Chrome 12 (OS X)
- Firefox 4 (OS X)
- Safari 5.0.5 (OS X)
Description:
- If the valueField is mapped to type:'int' field in the store, the setValue() function does not work consistently as expected. This was not a problem in Extjs 3.x
according to documentation setValue(string|array), however setting value with quotes as string does not work if the valueField is tied to an integer field.
myCombo.setValue('2'); //does not work
myCombo.setValue(2); //works as expected
This is a problem because I parse the History token into an object and all the values are strings. When the object is used to setValues of the form, it doesn't work properly.
Steps to reproduce the problem:
- create a combobox whose model has a defined idProperty with 'int' type.
- call the setValue() function with a quoted integer value
The result that was expected:
- The value of the combobox is set and the correct text(displayField) is selected from the underlaying store.
The result that occurs instead:
- The value is not set. The combobox displays a blank value.
Test Case:
Code:
<html>
<head>
<title>ExtJs 4 - combobox setValue bug</title>
<!-- Ext includes -->
<link rel="stylesheet" type="text/css" href="http://dev.sencha.com/deploy/ext-4.0.0/resources/css/ext-all.css" />
<script type="text/javascript" src="http://dev.sencha.com/deploy/ext-4.0.0/ext-all-debug.js"></script>
<script type="text/javascript">
Ext.Loader.setConfig({
enabled: true
});
Ext.require([
'Ext.form.field.ComboBox',
'Ext.form.FieldSet',
'Ext.tip.QuickTipManager',
'Ext.data.*'
]);
Ext.onReady(function() {
Ext.tip.QuickTipManager.init();
// Define the model for a State
Ext.define('State', {
extend: 'Ext.data.Model',
fields: [
{type: 'string', name: 'abbr'},
{type: 'string', name: 'name'},
{type: 'int', name: 'id'}
],
idProperty: 'id'
});
// The data for all states
var states = [
{"abbr":"AL","name":"Alabama","id":1},
{"abbr":"AK","name":"Alaska","id":2},
{"abbr":"AZ","name":"Arizona","id":3},
{"abbr":"AR","name":"Arkansas","id":4},
{"abbr":"CA","name":"California","id":5}
];
// The data store holding the states; shared by each of the ComboBox examples below
var store = Ext.create('Ext.data.Store', {
model: 'State',
data: states
});
// Simple ComboBox using the data store
var simpleCombo = Ext.create('Ext.form.field.ComboBox', {
fieldLabel: 'Select a single state',
renderTo: Ext.getBody(),
displayField: 'name',
width: 320,
labelWidth: 130,
store: store,
queryMode: 'local',
typeAhead: true,
valueField: 'id',
displayField: 'abbr'
});
Ext.create('Ext.Button', {
text: 'Set Value with quote',
renderTo: Ext.getBody(),
handler: function() {
simpleCombo.setValue('2');
alert("simpleCombo.setValue('2');");
}
});
Ext.create('Ext.Button', {
text: 'Set Value without quote',
renderTo: Ext.getBody(),
handler: function() {
simpleCombo.setValue(4);
alert("simpleCombo.setValue(4);");
}
});
});
</script>
</head>
<body>
<form id="history-form" class="x-hide-display">
<input type="hidden" id="x-history-field" />
<iframe id="x-history-frame"></iframe>
</form>
</body>
</html>
HELPFUL INFORMATION
Screenshot or Video:
See this URL for live test case: http://
Debugging already done:
- findRecord method under combobox calls for the store.findEact()
Code:
findRecord: function(field, value) {
var ds = this.store,
idx = ds.findExact(field, value);
return idx !== -1 ? ds.getAt(idx) : false;
},
findRecordByValue: function(value) {
return this.findRecord(this.valueField, value);
}
Code:
findExact: function(property, value, start) {
return this.data.findIndexBy(function(rec) {
return rec.get(property) === value;
},
this, start);
}
Possible fix:
Code:
/*------------------- override findExact function to solve problem with setValue function when passing string as int value -------------------*/
Ext.override(Ext.data.Store, {
findExact: function(property, value, start) {
return this.data.findIndexBy(function(rec) {
return rec.get(property) == value;
},
this, start);
}
});
Additional CSS used:
- only default ext-all-gray.css
Operating System:
-
Ext JS Premium Member
Looking at the source code the problematic line is this one under store
Simple override would fix this problem. However I'm not sure if this is by design or a bug.
Thanks
Code:
findExact: function(property, value, start) {
return this.data.findIndexBy(function(rec) {
return rec.get(property) === value;
},
this, start);
}
Mabye the findRecord method under combobox should be calling store.findRecord instead of store.findExact
Code:
findRecord: function(field, value) {
var ds = this.store,
idx = ds.findExact(field, value);
return idx !== -1 ? ds.getAt(idx) : false;
},
findRecordByValue: function(value) {
return this.findRecord(this.valueField, value);
}
-
Ext JS Premium Member
If you want to set a string value into it, why not just define the id field in the Model as a string (or 'auto')?
In other words, why declare the field in the model as an int if you don't want to treat it as such? Your usage (History token) implies that you're treating the value as a string, so I'd roll with that.
stevil
-
Ext JS Premium Member
Then the opposite wouldn't work, (i.e. setValue(2) ...)
In my model I want my ID to be int. There is no string mixed in.
This to me is a bug/problem. Since the only workaround I have here is to iterate though the decoded object from my history token and strip all quotes off the numeric values.
For now I've overridden the findExact function to use '==' operator instead. BTW, this was not a problem in Extjs 3.x
Thanks for the reply.
-
Sencha - Engineering Operations
thanks for the report, we've just introduced a new bug template that will help us migrate bugs from the forums to our bug tracker. Could you please update your ticket to follow this template so that we can address it faster?
-
Ext JS Premium Member

Originally Posted by
mike.estes
thanks for the report, we've just introduced a new bug template that will help us migrate bugs from the forums to our bug tracker. Could you please
update your ticket to follow this template so that we can address it faster?
Thanks. The original post is now formated.
-
Sencha - Engineering Operations
Thank you for updating your report using the template, I was able to confirm the behavior described is still present in the codebase and have put the report through, filed as EXTJSIV-3298
-
Thanks, this is fixed on the 4.0.7 branch
-
Sencha User
Hi,
I think the bug is back in 4.1.0.
Try replacing the 4.0 .js file by 4.1.0 file..
The full code :
Code:
<html>
<head>
<title>ExtJs 4 - combobox setValue bug</title>
<!-- Ext includes -->
<link rel="stylesheet" type="text/css" href="http://dev.sencha.com/deploy/ext-4.1.0-gpl/resources/css/ext-all.css" />
<script type="text/javascript" src="http://dev.sencha.com/deploy/ext-4.1.0-gpl/ext-all-debug.js"></script>
<script type="text/javascript">
Ext.Loader.setConfig({
enabled: true
});
Ext.require([
'Ext.form.field.ComboBox',
'Ext.form.FieldSet',
'Ext.tip.QuickTipManager',
'Ext.data.*'
]);
Ext.onReady(function() {
Ext.tip.QuickTipManager.init();
// Define the model for a State
Ext.define('State', {
extend: 'Ext.data.Model',
fields: [
{type: 'string', name: 'abbr'},
{type: 'string', name: 'name'},
{type: 'int', name: 'id'}
],
idProperty: 'id'
});
// The data for all states
var states = [
{"abbr":"AL","name":"Alabama","id":1},
{"abbr":"AK","name":"Alaska","id":2},
{"abbr":"AZ","name":"Arizona","id":3},
{"abbr":"AR","name":"Arkansas","id":4},
{"abbr":"CA","name":"California","id":5}
];
// The data store holding the states; shared by each of the ComboBox examples below
var store = Ext.create('Ext.data.Store', {
model: 'State',
data: states
});
// Simple ComboBox using the data store
var simpleCombo = Ext.create('Ext.form.field.ComboBox', {
fieldLabel: 'Select a single state',
renderTo: Ext.getBody(),
displayField: 'name',
width: 320,
labelWidth: 130,
store: store,
queryMode: 'local',
typeAhead: true,
valueField: 'id',
displayField: 'abbr'
});
Ext.create('Ext.Button', {
text: 'Set Value with quote',
renderTo: Ext.getBody(),
handler: function() {
simpleCombo.setValue('2');
alert("simpleCombo.setValue('2');");
}
});
Ext.create('Ext.Button', {
text: 'Set Value without quote',
renderTo: Ext.getBody(),
handler: function() {
simpleCombo.setValue(4);
alert("simpleCombo.setValue(4);");
}
});
});
</script>
</head>
<body>
<form id="history-form" class="x-hide-display">
<input type="hidden" id="x-history-field" />
<iframe id="x-history-frame"></iframe>
</form>
</body>
</html>
-
Ext JS Premium Member
It was actually never fixed in the final 4.0.7 build.