-
9 Oct 2012 12:56 AM #1
Answered: Ext.field.Spinner.setValue() problem on Android 4.0.3 default browser
Answered: Ext.field.Spinner.setValue() problem on Android 4.0.3 default browser
Hi,
I have built a custom slider field, that is constructed by a 'spinner' and a 'slider'. Both are capable of changing the spinner's value (the range is 0-2, where the increment is set to 0.1):
https://surf-space.com/tests/customslider/
Every 'change' event on the slider, calls the spinner's setValue() function and modify it.
Problem is, on Android 4.0.3 native browser, most of the spinner's setValue() calls are being "stuck" or "delayed". That is, the change is not being rendered on the view.
So, for example, if the spinner and the slider are both set to 1, and I now drag the slider to 1.5, the spinner's shown value will remain 1. At this state I see 2 unexpected behaviors:
1. Dragging the slider to a new value, say 1.8, will change the spinner's shown value to 1.5 (the next chage will make it 1.8 and so on).
2. Pressing the spinner '+' button will increment the 1.5 (not the shown value 1) by 0.1, resulting 1.6 spinner value.
It seems like the value is changes but not rendered. Is there a way of explicitly calling the spinner's rendering mechanism?
Attached below is my view's code.
Regards, Roei.
Code:Ext.define('Surfspace.view.ReportPost', { extend: 'Ext.form.Panel', xtype: 'reportPost', fullscreen: true, config: { styleHtmlContent:true, items: [ { xtype: 'fieldset', title: 'Surf Report', items: [ { xtype: 'spinnerfield', label: 'Wave height', id: 'waveheightspinner', minValue: 0, maxValue: 2, increment: 0.1, cycle: false, component: { type: 'text'}, applyValue: function(newValue, oldValue){ console.log('newValue: ' + newValue + ' oldValue: ' + oldValue); var waveheighslider = Ext.getCmp("waveheighslider"); // sometimes the slider and the spinner's value are x.x999999999 or x.x00000000001, so this is a quick fix for that. var sliderval = Math.round(waveheighslider._value[0] * 10)/10; newValue = Math.round(newValue * 10)/10; if (sliderval !== newValue) { console.log('change was done by spinner'); waveheighslider.setValue(newValue); } return newValue; }, }, Ext.create('Ext.Panel', { layout: 'hbox', items: [ { xtype: 'slider', id: 'waveheighslider', value: 0, minValue: 0, maxValue: 2, increment: 0.1, margin: '1%', flex: 9, listeners: { change: function(me, thumb, newValue, oldValue, eOpts) { var val = Math.round(newValue * 10)/10; var waveheightspinner = Ext.getCmp("waveheightspinner").setValue(val); }, } },]}), ] }, ], } });
-
Best Answer Posted by haduki
Sorry for my poor english.
That's right.
But there is no 'applyValue' var defined in the config object of 'Ext.field.Field'.
You can try this.If the problem still remains i would have no idea.Code:Ext.define('class',{ config: { name:'', applyName:function(){} }, applyName:function(){}, applyApplyName:function(){} })
Code:spinner listener { change:function(me,newValue,oldValue){ console.log('newValue: ' + newValue + ' oldValue: ' + oldValue); var waveheighslider = Ext.getCmp("waveheighslider"); waveheighslider.setValue(newValue); } }
-
9 Oct 2012 2:06 AM #2
correct way:
You should not override anything which did not defined in config when you create instance.Code:{ xtype: 'spinnerfield', label: 'Wave height', id: 'waveheightspinner', minValue: 0, maxValue: 2, increment: 0.1, cycle: false, component: { type: 'text'}, listeners: { change:function(me,newValue,oldValue){ console.log('newValue: ' + newValue + ' oldValue: ' + oldValue); var waveheighslider = Ext.getCmp("waveheighslider"); // sometimes the slider and the spinner's value are x.x999999999 or x.x00000000001, so this is a quick fix for that. var sliderval = Math.round(waveheighslider._value[0] * 10)/10; console.info(waveheighslider._value[0]); newValue = Math.round(newValue * 10)/10; if (sliderval !== newValue) { console.log('change was done by spinner'); waveheighslider.setValue(newValue); } } } }
Code:Ext.define('Class',{ config: { name:'' }, applyName:function(){}//<--you can do this }); Ext.create('Class',{ name:'name', applyName:function(){}//<--you can NOT do this }); //if you want to override,you have to define a new class which extend by/override to old classI write English by translator.
-
9 Oct 2012 2:37 AM #3
Hi @haduki, and thank you for the quick reply.
The 'value' var is originally defined in the config object of 'Ext.field.Field', which 'Ext.field.Spinner' inherits from. In addition, 'Ext.field.Spinner' also defines an explicit applyValue() function. So I don't understand what you mean.You should not override anything which did not defined in config when you create instance.
Anyway, your suggested solution of replacing applyValue() with change() did not work, the problem remains.
-
9 Oct 2012 3:04 AM #4
Sorry for my poor english.
That's right.
But there is no 'applyValue' var defined in the config object of 'Ext.field.Field'.
You can try this.If the problem still remains i would have no idea.Code:Ext.define('class',{ config: { name:'', applyName:function(){} }, applyName:function(){}, applyApplyName:function(){} })
Code:spinner listener { change:function(me,newValue,oldValue){ console.log('newValue: ' + newValue + ' oldValue: ' + oldValue); var waveheighslider = Ext.getCmp("waveheighslider"); waveheighslider.setValue(newValue); } }I write English by translator.
-
9 Oct 2012 3:37 AM #5
I am sorry, but I don't understand the point you are trying to make.
applyValue() is not a var, it is a function that automatically added to the 'Ext.field.Field' class because of the Sencha Class System. What I meant to say, is that the class 'Ext.field.Spinner', which inherit from 'Ext.field.Field', explicitly implement the applyValue() function. This is a snippet of 'Ext.field.Spinner' code:
So I'm only trying to override this function.Code:applyValue: function(value) { value = parseFloat(value); if (isNaN(value) || value === null) { value = this.getDefaultValue(); } //round the value to 1 decimal value = Math.round(value * 10) / 10; return this.callParent([value]); },
Anyway, your suggested solution does not seem like what is causing the problem.
-
9 Oct 2012 4:08 AM #6
Please read document about Sencha Class System again.
Where wrote you can override something when you create a instance?
You can override only when you define a new class.
Code:Ext.define('MyClass',{ config:{ name:'', applyName:'' }, constructor:function(config){ this.initConfig(config); }, applyName:function(name){console.info('applyName:'+name);return name;}, applyApplyName:function(name){console.info('applyApplyName:'+name);return name;} }); var instance=Ext.create('MyClass',{ name:'aaa', applyName:'bbb' }); console.info(instance.getName()); console.info(instance.getApplyName()); instance.setName('cccc'); instance.setApplyName('dddd'); //Could you tell me what will happen?where is your override 'applyName' ? //You can not do that!This is class system bug.I write English by translator.
-
9 Oct 2012 4:55 AM #7
Ok, now I see your point. Defining:
is like setting the applyValue() function inside the config object of 'Ext.field.Spinner'.Code:{ xtype: 'spinnerfield', applyValue: function() }
-
9 Oct 2012 5:05 AM #8
I haven't notice the last code box you have provided.
This does seem to solve the issue. Thank you.Code:spinner listener { change:function(me,newValue,oldValue){ console.log('newValue: ' + newValue + ' oldValue: ' + oldValue); var waveheighslider = Ext.getCmp("waveheighslider"); waveheighslider.setValue(newValue); } }
I have originally added the 'if' clause:
Because I was afraid it may cause an infinite loop between the spinner and slider, triggering each other's 'change' event.Code:if (sliderval !== newValue) { console.info('change was done by spinner'); waveheighslider.setValue(newValue); }
1. Is the 'change' event will never be triggered (on any possible browser/device) if the setValue() function is called with the current value?
2. What do you think caused this error/behavior? What is wrong with my 'if' clause?


Reply With Quote