PDA

View Full Version : [OPEN-1328] NumberField setValue() bug when the field has not been rendered yet.



Daniil
7 Oct 2010, 7:56 AM
Ext version tested:


Ext 3.3.0



Adapter used:


ext


css used:


only default ext-all.css





Browser versions tested against:


IE8
FF3 (firebug 1.3.0.10 installed)



Operating System:


WinXP



Description:


A NumberField has not been rendered yet;
A decimalSeparator differs from "." (for example, ",");
The setValue() method doesn't work as expected. Then the NumberField will be rendered as blank.


Test Case:

Code:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title id='title'>NumberField Bug</title>

<!-- ** CSS ** -->
<!-- base library -->
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />



<!-- ** Javascript ** -->
<!-- base library -->
<script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../../ext-all-debug.js"></script>



<script type="text/javascript">
Ext.BLANK_IMAGE_URL = '../../resources/images/default/s.gif';

Ext.onReady(function(){
new Ext.TabPanel({
renderTo: "tb_Container",
height: 50,
items: [{
items: [{
xtype: "button",
text: "Click me and go to Tab 2",
listeners: {
click: {
fn: function(el, e){
Ext.getCmp("NumberField1").setValue(100.5);
}
}
}
}],
layout: "auto",
title: "Tab 1"
}, {
items: {
id: "NumberField1",
xtype: "numberfield",
decimalSeparator: ","
},
layout: "auto",
title: "Tab 2"
}],
activeTab: 0
});
});
</script>

</head>
<body>
<div id="tb_Container"></div>
</body>
</html>
Steps to reproduce the problem:


Click on the button
Go to Tab 2
NumberField is blank



The result that was expected:


NumberField is NOT blank



The result that occurs instead:


NumberField is blank


Debugging already done:


yes. After setValue() the NumberField.value is string with non-number format "100,5". And during rendering isNan(value) is true.



Possible fix:


Seems there must be checking on rendered within setValue()

steffenk
7 Oct 2010, 10:54 AM
i don't see the bug. After load the number field is not rendered, that's normal with tab panels. So how should there a return for Ext.getCmp("NumberField1")?
Now, reload, click on Tab2, back to Tab1 and click the button, work as expected.

The other thing, to allow different decimalSeperator, the value has to handled as string. You set it to ",", so the output is correct, and you set the value with float, so all is fine at this place.

Daniil
7 Oct 2010, 11:25 AM
Hi,

As far as I know getCmp() method returns an instance of component, regardless of whether it is rendered or not.

So, if you replace

Ext.getCmp("NumberField1").setValue(100.5);
with

Ext.getCmp("NumberField1").value = 100.5;

you'll see that the code works fine.

steffenk
7 Oct 2010, 11:41 AM
Ext.getCmp("NumberField1").value sets the value of the config, so it will be used when the element is rendered. setValue change the value of a rendered element, can't work if the element isn't rendered.

Daniil
7 Oct 2010, 12:39 PM
Look at the setValue() of Ext.form.Field.


setValue : function(v){
this.value = v;
if(this.rendered){
this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
this.validate();
}
return this;
}

So, try to replace NumberField with TextField in my example and you will see that setValue() works greatly with not rendered components.

steffenk
7 Oct 2010, 1:50 PM
I debugged partly, and after setValue the value of NumberField is correct. So it gets losed while render, and i agree its a bug.

Daniil
8 Oct 2010, 10:12 AM
Waiting for what ExtJS team says.

Daniil
13 Oct 2010, 1:32 PM
Bump...
Any update?

ChrisR
21 Mar 2011, 6:28 AM
I've researched a little more into this issue and noticed that it's related to the decimalSeparator config option.

When you have set the decimalSeparator set to something else than a dot, setValue will not work if the numberfield isn't rendered yet, in all other cases it will.

Check http://jsfiddle.net/chrisramakers/KUqM9/


@Daniil: Do you have the decimalSeparated modified too?

Any input from the ExtJS team is appreciated!

ChrisR
21 Mar 2011, 7:45 AM
I've pinned it down to the setValue function of NumberField. If the field isn't rendered yet the function gets called twice

* once when not rendered yet, assigning the value to this.value
* a second time when actually rendering the field and getting this.value

The problem is that in the second pass not the valid float value is passed but the displayed value with modified decimal separator. Thus it gets emptied by the call to fixPrecision(v)


Ext.override(Ext.form.NumberField, {
setValue : function(v) {
v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
v = this.fixPrecision(v);
v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
return Ext.form.NumberField.superclass.setValue.call(this, v);
}
});

Daniil
21 Mar 2011, 8:37 AM
@Daniil: Do you have the decimalSeparated modified too?


Hi ChrisR,

Yes, the decimal separator is "," in the sample code in the initial post.

And yes again, I had the same result after investigating/debugging as yours.

ChrisR
21 Mar 2011, 12:41 PM
I've pinned it down to the setValue function of NumberField. If the field isn't rendered yet the function gets called twice

* once when not rendered yet, assigning the value to this.value
* a second time when actually rendering the field and getting this.value

The problem is that in the second pass not the valid float value is passed but the displayed value with modified decimal separator. Thus it gets emptied by the call to fixPrecision(v)

You can easily fix it by applying this override. I don't know what implications it has for the further functioning of the NumberField compononent, maybe some of the Ext team can elaborate on this?


Ext.override(Ext.form.NumberField, {
setValue : function(v) {
v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
v = this.fixPrecision(v);
v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
return Ext.form.NumberField.superclass.setValue.call(this, v);
}
});

Daniil
22 Mar 2011, 2:02 AM
Well, I used the fix that I posted, there have not been any problem yet.

I just hope that it would be fixed in ExtJS sources.

But as far as I can understand, ExtJS team priority is 4.0 now. And, sure, premium members:)

Anyway, ExtJS is the great product:)