Hybrid View

    Thank you for reporting this bug. We will make it our priority to review this report.
  1. #1
    Sencha User tobiu's Avatar
    Join Date
    May 2007
    Location
    Munich (Germany)
    Posts
    2,679
    Vote Rating
    112
    tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all

      0  

    Default [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:

    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;
        }
    });
    i had to write "Math" instead of "MATH", since i can not access the attribute with an override.

    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
    Best regards
    Tobias Uhlig
    __________

    S-CIRCLES Social Network Engine

  2. #2
    Sencha User Jamie Avins's Avatar
    Join Date
    Mar 2007
    Location
    Redwood City, California
    Posts
    3,661
    Vote Rating
    20
    Jamie Avins is a jewel in the rough Jamie Avins is a jewel in the rough Jamie Avins is a jewel in the rough

      0  

    Default


    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.

  3. #3
    Sencha User tobiu's Avatar
    Join Date
    May 2007
    Location
    Munich (Germany)
    Posts
    2,679
    Vote Rating
    112
    tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all

      0  

    Default


    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
    Best regards
    Tobias Uhlig
    __________

    S-CIRCLES Social Network Engine

  4. #4
    Sencha User tobiu's Avatar
    Join Date
    May 2007
    Location
    Munich (Germany)
    Posts
    2,679
    Vote Rating
    112
    tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all

      0  

    Default


    hi jamie,

    i build a new version of the fix:

    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;
        }
    });
    i removed the max (clientWidth, offsetWidth) check and improved the new routine a bit more:
    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
    Code:
    ,deferredRender : false
    ,layoutOnTabChange : false
    and hideMode -> display. so, basically we don't need layoutOnTabchange anymore if the fix works as i think it does.

    here an example:

    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();
    });
    try it out with and without the fix.


    kind regards,
    tobiu
    Best regards
    Tobias Uhlig
    __________

    S-CIRCLES Social Network Engine

  5. #5
    Sencha User Jamie Avins's Avatar
    Join Date
    Mar 2007
    Location
    Redwood City, California
    Posts
    3,661
    Vote Rating
    20
    Jamie Avins is a jewel in the rough Jamie Avins is a jewel in the rough Jamie Avins is a jewel in the rough

      0  

    Default


    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.

  6. #6
    Sencha User steffenk's Avatar
    Join Date
    Jul 2007
    Location
    Haan, Germany
    Posts
    2,664
    Vote Rating
    7
    steffenk has a spectacular aura about steffenk has a spectacular aura about steffenk has a spectacular aura about

      0  

    Default


    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

  7. #7
    Sencha User tobiu's Avatar
    Join Date
    May 2007
    Location
    Munich (Germany)
    Posts
    2,679
    Vote Rating
    112
    tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all

      0  

    Default


    after further testing, i prefer

    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;
        }
    });
    again


    for details, just ask.
    Best regards
    Tobias Uhlig
    __________

    S-CIRCLES Social Network Engine

Similar Threads

  1. [CLOSED]An Ext.grid.GridPanel.processEvent fix proposal
    By Dmitry Ovsyanko in forum Ext 3.x: Bugs
    Replies: 1
    Last Post: 10 Mar 2010, 7:01 AM
  2. Replies: 3
    Last Post: 16 Aug 2009, 12:18 PM
  3. Replies: 6
    Last Post: 18 Jul 2009, 12:30 PM
  4. Replies: 1
    Last Post: 14 Apr 2008, 11:11 AM
  5. getWidth method in YAHOO.ext.Element
    By jclawson in forum Ext 1.x: Bugs
    Replies: 6
    Last Post: 4 Mar 2007, 11:52 PM

Thread Participants: 4