stever
30 Apr 2009, 6:56 PM
This bug keeps coming up for months, years even. The answer is always the same -- have the parent hidden container to use hide via offsets. But there are other ways, including a mitigation to make the error less bad if you ignore the advice. The big issue is the trigger image wrapping to the wrong (left) side instead of the right side.
Can a dev comment on why this code is this way (TriggerField):
// private
onResize : function(w, h){
Ext.form.TriggerField.superclass.onResize.call(this, w, h);
if(typeof w == 'number'){
this.el.setWidth(this.adjustWidth('input', w - this.trigger.getWidth()));
}
this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
},
and not this way:
// private
onResize : function(w, h){
Ext.form.TriggerField.superclass.onResize.call(this, w, h);
if(typeof w == 'number'){
this.el.setWidth(this.adjustWidth('input', w - this.trigger.getWidth()));
}
this.wrap.setWidth(w);
},
In this case the image is on the correct side, the width opf the whole thing seems correct, the only issue is that the input element hides behind the trigger image and doesn't look perfect (though quite usable, as opposed to the current situation).
Personally I do this:
// private
triggerDefaultWidth: 17,
onResize : function(w, h){
Ext.form.TriggerField.superclass.onResize.call(this, w, h);
if(typeof w == 'number'){
this.el.setWidth(this.adjustWidth('input', w - (this.hideTrigger ? 0 : this.trigger.getWidth() || this.triggerDefaultWidth)));
}
this.wrap.setWidth(w);
},
This takes a triggerDefaultWidth as a hint if the image is hidden. I doubt many people change the Ext CSS to change the trigger width, and if they were, then they could figure out how to change the triggerDefaultWidth or use the hide by offsets. But I think this would be the fix for 99% of your users. AND I know people search for this issue, so I tried to use the words that might search for, like: tabpanel, tabs, defferedRender, etc. ;)
BTW: a couple of other things... the triggerField onRender does a call to a setWidth:
// private
onRender : function(ct, position){
Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
this.wrap = this.el.wrap({cls: "x-form-field-wrap"});
this.trigger = this.wrap.createChild(this.triggerConfig ||
{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
if(this.hideTrigger){
this.trigger.setDisplayed(false);
}
this.initTrigger();
if(!this.width){
this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
}
if(!this.editable){
this.editable = true;
this.setEditable(false);
}
},
I just take out the lines in red in my version. AfterRender calls setSize which calls onResize which does a better job anyhow.
OK, OK, one more thing... twintriggerfield needs its own onResize. It doesn't even take into account that there are two trigger images when calculating the width of the input el. I noticed I hadn't moved that fix from v2 to v3 yet...
Can a dev comment on why this code is this way (TriggerField):
// private
onResize : function(w, h){
Ext.form.TriggerField.superclass.onResize.call(this, w, h);
if(typeof w == 'number'){
this.el.setWidth(this.adjustWidth('input', w - this.trigger.getWidth()));
}
this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
},
and not this way:
// private
onResize : function(w, h){
Ext.form.TriggerField.superclass.onResize.call(this, w, h);
if(typeof w == 'number'){
this.el.setWidth(this.adjustWidth('input', w - this.trigger.getWidth()));
}
this.wrap.setWidth(w);
},
In this case the image is on the correct side, the width opf the whole thing seems correct, the only issue is that the input element hides behind the trigger image and doesn't look perfect (though quite usable, as opposed to the current situation).
Personally I do this:
// private
triggerDefaultWidth: 17,
onResize : function(w, h){
Ext.form.TriggerField.superclass.onResize.call(this, w, h);
if(typeof w == 'number'){
this.el.setWidth(this.adjustWidth('input', w - (this.hideTrigger ? 0 : this.trigger.getWidth() || this.triggerDefaultWidth)));
}
this.wrap.setWidth(w);
},
This takes a triggerDefaultWidth as a hint if the image is hidden. I doubt many people change the Ext CSS to change the trigger width, and if they were, then they could figure out how to change the triggerDefaultWidth or use the hide by offsets. But I think this would be the fix for 99% of your users. AND I know people search for this issue, so I tried to use the words that might search for, like: tabpanel, tabs, defferedRender, etc. ;)
BTW: a couple of other things... the triggerField onRender does a call to a setWidth:
// private
onRender : function(ct, position){
Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
this.wrap = this.el.wrap({cls: "x-form-field-wrap"});
this.trigger = this.wrap.createChild(this.triggerConfig ||
{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
if(this.hideTrigger){
this.trigger.setDisplayed(false);
}
this.initTrigger();
if(!this.width){
this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
}
if(!this.editable){
this.editable = true;
this.setEditable(false);
}
},
I just take out the lines in red in my version. AfterRender calls setSize which calls onResize which does a better job anyhow.
OK, OK, one more thing... twintriggerfield needs its own onResize. It doesn't even take into account that there are two trigger images when calculating the width of the input el. I noticed I hadn't moved that fix from v2 to v3 yet...