-
13 Jul 2010 5:42 AM #1
[CLOSED] Ext.Element -> getWidth + fix
[CLOSED] Ext.Element -> getWidth + fix
hi team,
this might be the biggest bugfix i posted so far, since it will resolve quite a bunch of issues.
in the past i had several problems with rendering hidden items and width calculations, most were tabbed forms with deferredRender: false.
+ i had comboBoxes that were 17px (the width of the trigger) to wide
+ errorIcons displayed over the fieldLabel
+ sliders with the thumb always at zero
and many more issues. this all went down to the point, that the width-calculations returned 0 if rendered hidden. i used hideMode: offsets quite a lot because of this. the solution i found also works with the default display-mode.
so, here it is:
i had to write "Math" instead of "MATH", since i can not access the attribute with an override.Code:Ext.override(Ext.Element, { getWidth : function(contentWidth){ var me = this, dom = me.dom, hidden = Ext.isIE && me.isStyle('display', 'none'), w = Math.max(dom.offsetWidth || parseInt(dom.style.width, 10), hidden ? 0 : dom.clientWidth) || 0; w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr"); return w < 0 ? 0 : w; } });
here is a small usecase, showing my sliderField usecase with normal hideMode:display.
tested in ff3.6, ie8 and chrome. the fix for getHeight should work the same way.
Code:Ext.onReady(function(){ Ext.override(Ext.Element, { getWidth : function(contentWidth){ var me = this, dom = me.dom, hidden = Ext.isIE && me.isStyle('display', 'none'), w = Math.max(dom.offsetWidth || parseInt(dom.style.width, 10), hidden ? 0 : dom.clientWidth) || 0; w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr"); return w < 0 ? 0 : w; } }); new Ext.form.FormPanel({ renderTo: document.body, width:600, height:250, layout:'fit', border:false, labelWidth : 100, items : [{ xtype: 'tabpanel', activeTab: 0, deferredRender: false, layoutOnTabChange: true, plain:true, defaults:{autoScroll: true}, items:[{ title: 'Tab 1', html: "My content was added during construction." },{ title: 'Tab 2', layout: 'form', items: [{ fieldLabel: 'Sliderfield', maxValue : 500, minValue : 0, value : 250, width : 200, xtype : 'sliderfield' }] } ] }] }); });
kind regards,
tobiu
-
13 Jul 2010 11:34 AM #2Sencha - Sencha Touch Dev Team
- Join Date
- Mar 2007
- Location
- Redwood City, California
- Posts
- 3,651
- Vote Rating
- 14
Its an interesting workaround for the problem but I don't think we can generalize it to the extent where it's included in Element.
-
14 Jul 2010 4:50 AM #3
hi jamie,
please don't underestimate the override, it fixes many other tickets as well.
for example the triggerField-issue of ticket 1110:
http://www.sencha.com/forum/showthread.php?103405
kind regards,
tobias
-
14 Jul 2010 7:32 AM #4
hi jamie,
i build a new version of the fix:
i removed the max (clientWidth, offsetWidth) check and improved the new routine a bit more:Code:Ext.override(Ext.Element, { getWidth : function(contentWidth){ var me = this, dom = me.dom, w = dom.offsetWidth|| 0; w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr"); if(w <= 0){ w = parseInt(dom.style.width, 10) || 0; while(dom.parentNode){ if(dom.parentNode.style){ w += (parseInt(dom.parentNode.style.marginLeft, 10) || 0); w += (parseInt(dom.parentNode.style.paddingLeft, 10) || 0); } dom = dom.parentNode; } } return w; } });
it checks all parentNodes for margins and paddings.
since this might increase the needed execution-time, it is only used when the width is 0.
otherwise it could replace the whole old mechanism.
the advantage of this version is:
you can use tabpanels with
and hideMode -> display. so, basically we don't need layoutOnTabchange anymore if the fix works as i think it does.Code:,deferredRender : false ,layoutOnTabChange : false
here an example:
try it out with and without the fix.Code:Ext.onReady(function(){ Ext.override(Ext.Element, { getWidth : function(contentWidth){ var me = this, dom = me.dom, w = dom.offsetWidth|| 0; w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr"); if(w <= 0){ w = parseInt(dom.style.width, 10) || 0; while(dom.parentNode){ if(dom.parentNode.style){ w += (parseInt(dom.parentNode.style.marginLeft, 10) || 0); w += (parseInt(dom.parentNode.style.paddingLeft, 10) || 0); } dom = dom.parentNode; } console.log(w); } return w; } }); var tabs = new Ext.FormPanel({ labelWidth : 75 ,border : false ,items: { xtype : 'tabpanel' ,activeTab : 0 ,deferredRender : false //,layoutOnTabChange : true ,id : 'tp' ,anchor : '100% 100%' ,style : 'margin-bottom:10px;' ,defaults:{ autoScroll : true ,bodyStyle :'padding:10px;' } ,items:[{ title : 'Personal Details', layout : 'form', id : 'tab1' ,items: [{ anchor : '-20' ,autoHeight : true ,title : 'Customer' ,checkboxName : 'checkAnimation' ,checkboxToggle : true ,xtype : 'fieldset' ,defaults: { anchor : '-22' ,width : 230 ,msgTarget : 'side' }, defaultType: 'textfield', items :[{ fieldLabel: 'First Name', allowBlank: false, name: 'first', id: 'focus1' },{ fieldLabel: 'Last Name', allowBlank: false, name: 'last' },{ fieldLabel: 'Company', name: 'company', value: 'Ext JS' }, { fieldLabel: 'Email', name: 'email', vtype:'email' },{ fieldLabel: 'Business', name: 'business' },{ fieldLabel: 'Mobile', name: 'mobile' },{ fieldLabel: 'Fax', name: 'fax' }] }] },{ title : 'Phone Numbers' ,layout : 'form' ,id : 'tab2' ,defaults : { width : 230 ,anchor : '-22' ,msgTarget : 'side' } ,defaultType: 'textfield', items: [{ fieldLabel: 'Home', allowBlank: false, name: 'home', value: '(888) 555-1212' }, { fieldLabel: 'Email', allowBlank: false, name: 'email', vtype:'email' },{ fieldLabel: 'Business', name: 'business' },{ fieldLabel: 'Mobile', name: 'mobile' },{ fieldLabel: 'Fax', name: 'fax', style:'margin-bottom:10px;' }] }] } }); var myWindow = new Ext.Window({ height : 400 ,border : false ,layout : 'fit' ,title : 'a window' ,width : 400 ,items : tabs ,buttons: [{ text: 'Step 1', handler : function(){ Ext.getCmp('focus1').focus(); Ext.getCmp('tp').setActiveTab(1); } },{ text: 'Step 2', handler : function(){ Ext.getCmp('tp').setActiveTab(0); } }] }); myWindow.show(); });
kind regards,
tobiu
-
14 Jul 2010 9:25 AM #5Sencha - Sencha Touch Dev Team
- Join Date
- Mar 2007
- Location
- Redwood City, California
- Posts
- 3,651
- Vote Rating
- 14
I understand the logic behind what you are doing, but the potential impact to existing applications doing this implementation is too large for us to include it.
-
15 Jul 2010 6:21 AM #6
Hi,
i tested the patch with a big application of mine, and it has no side effects, all is working as expected.vg Steffen
--------------------------------------
Release Manager of TYPO3 4.5
energlobe.de - german online magazine
-
20 Jul 2010 8:10 AM #7
after further testing, i prefer
againCode:Ext.override(Ext.Element, { getWidth : function(contentWidth){ var me = this, dom = me.dom, hidden = Ext.isIE && me.isStyle('display', 'none'), w = Math.max(dom.offsetWidth || parseInt(dom.style.width, 10), hidden ? 0 : dom.clientWidth) || 0; w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr"); return w < 0 ? 0 : w; } });
for details, just ask.
-
22 Aug 2011 4:41 AM #8
Problem sems still present or i have done something wrong

tried with and without the workaround, no difference
first test at dev.sencha.com
pic0.jpgpic1.jpg
second test with our app + override
pic2.jpgpic3.jpg
used: Ext 3.4.0
at the moment iam analysing getWidth
the hidden elements get zero as width
log visible elements
log hidden elementsCode:after w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");14ext-gen1014 after w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");445ext-gen1012 after w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");14ext-gen1021 after w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");445ext-gen1019
Code:after w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");0ext-gen1063 after w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");0ext-gen1061 after w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");0ext-gen1070 after w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");0ext-gen1068
Edit:Code:Ext.override ( Ext.Element, { getWidth : function( contentWidth ) { var me = this, dom = me.dom, hidden = Ext.isIE && me.isStyle ( 'display', 'none' ), w = Math.max ( dom.offsetWidth || parseInt ( dom.style.width, 10 ), hidden ? 0 : dom.clientWidth ) || 0; w = !contentWidth ? w : w - me.getBorderWidth ( "lr" ) - me.getPadding ( "lr" ); return w < 0 ? 0 : w; } } ); var baseurl = ''; Ext.namespace ( "Sys" ); Ext.namespace ( "Sys.cache" ); Ext.namespace ( "Sys.dialog" ); var PowerPoints = [new Ext.Panel ( { title: 'Ambulante Leistungen', layout : 'form', defaultType: 'sliderfield', border : false, autoScroll: true, padding: '5', items: [ { fieldLabel : 'Ärztliche Behandlung ambulant (Art und Höhe)', name: 'Im_203', id: 'Im_203', ctCls: 'custom-slider', increment: 8, minValue: 0, maxValue: 100, value: 0, overlap: false }, { fieldLabel : 'Gebührenordnung für Ärzte, ambulant', name: 'Im_1', id: 'Im_1', ctCls: 'custom-slider', increment: 7, minValue: 0, maxValue: 100, value: 0, overlap: false } ] } ),new Ext.Panel ( { title: 'Stationäre Leistungen', layout : 'form', defaultType: 'sliderfield', border : false, autoScroll: true, padding: '5', items: [ { fieldLabel : 'Stationäre Pflegeklasse', name: 'Im_19', id: 'Im_19', ctCls: 'custom-slider', increment: 4, minValue: 0, maxValue: 100, value: 0, overlap: false }, { fieldLabel : 'Haushaltshilfe', name: 'Im_280', id: 'Im_280', ctCls: 'custom-slider', increment: 5, minValue: 0, maxValue: 100, value: 0, overlap: false }, { fieldLabel : 'Ärztliche Behandlung stationär (Art und Höhe)', name: 'Im_20', id: 'Im_20', ctCls: 'custom-slider', increment: 2, minValue: 0, maxValue: 100, value: 0, overlap: false } ] } )] Sys.dialog.facts = function( config ) { if ( !config ) { config = {}; } config.maximizable = true; config.modal = false; config.resizable = true; config.layout='fit'; config.width = 400; config.height = 600; config.title = 'Einstellung der Wichtigkeit'; config.id = 'dialog-importance-preference'; config.buttons = [ { text: 'Speichern', handler: function() { var val = this.form.getForm ().getValues (); Ext.Ajax.request ( { url: baseurl + 'important/save', method: 'POST', params: val, success: function( a ) { msg = Ext.util.JSON.decode ( a.responseText ); if ( msg.success ) { // Sys.gridStore.reload () } else { Ext.Msg.alert ( 'Failure', msg.message ); } }, failure: function( form, action ) { switch ( action.failureType ) { case Ext.form.Action.CLIENT_INVALID: Ext.Msg.alert ( 'Failure', 'Form fields may not be submitted with invalid values' ); break; case Ext.form.Action.CONNECT_FAILURE: Ext.Msg.alert ( 'Failure', 'Ajax communication failed' ); break; case Ext.form.Action.SERVER_INVALID: Ext.Msg.alert ( 'Failure', action.result.message ); } }, scope:this } ); }, scope: this }, { text: 'Schließen', handler: function() { this.close (); }, scope: this } ]; config.items = this.form = new Ext.form.FormPanel ( { url: baseurl + 'calculate/doRequest', border:false, labelAlign:'top', layout: 'fit', items:[ { split:true, border:false, layout:'accordion', items: [ config.powerPoints ] } ] } ); config.tbar = [ { text: 'Regler zurücksetzen', handler: function() { var list = this.form.getForm ().items.items; for ( i = 0; i < list.length; i++ ) { list[i].setValue ( 100 ); } }, scope: this } ]; config.listeners = { show: function() { //Sys.util.spot.show('dialog-importance-preference'); }, hide: function() { //Sys.util.spot.hide(); }, scope: this }; Sys.dialog.facts.superclass.constructor.call ( this, config ); } Ext.extend ( Sys.dialog.facts, Ext.Window, {} ); Sys.dialog.Facts = new Sys.dialog.facts ( { powerPoints: PowerPoints } ); Sys.dialog.Facts.show ();
visible elements
function Ext.Element.getWidth()
dom.offsetWidth == 14
dom.style.width == ""
dom.clientWidth == 14
hidden elements
function Ext.Element.getWidth()
dom.offsetWidth == 0
dom.style.width == ""
dom.clientWidth == 0
-
8 Oct 2012 9:38 PM #9
Code:Ext.override(Ext.Element, { getWidth : function (contentWidth) { var me = this, dom = me.dom, hidden = Ext.isIE && me.isStyle('display', 'none'); var outerWidth = me.getBorderWidth("lr") + me.getPadding("lr"); var styleWidth = parseInt(dom.style.width, 10) + outerWidth; var w = Math.max(dom.offsetWidth || styleWidth, hidden ? 0 : dom.clientWidth) || 0; w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr"); return w < 0 ? 0 : w; } });
Thank you for reporting this bug. We will make it our priority to review this report.
Similar Threads
-
[CLOSED]An Ext.grid.GridPanel.processEvent fix proposal
By Dmitry Ovsyanko in forum Ext 3.x: BugsReplies: 1Last Post: 10 Mar 2010, 7:01 AM -
[CLOSED][3.??] Bug + fix for Ext.ListView and IE6
By mvt in forum Ext 3.x: BugsReplies: 3Last Post: 16 Aug 2009, 12:18 PM -
[CLOSED][3.0.0] Event handler arguments receive DOM element instead of Ext.Element
By jherfurth in forum Ext 3.x: BugsReplies: 6Last Post: 18 Jul 2009, 12:30 PM -
[2.0][CLOSED] Ext.get/Ext.getDom does not fix IE's document.getElementById bug
By noelito in forum Ext 2.x: BugsReplies: 1Last Post: 14 Apr 2008, 11:11 AM -
getWidth method in YAHOO.ext.Element
By jclawson in forum Ext 1.x: BugsReplies: 6Last Post: 4 Mar 2007, 11:52 PM


Reply With Quote