Thank you for reporting this bug. We will make it our priority to review this report.
  1. #1
    Sencha User
    Join Date
    Aug 2008
    Location
    Minnesota
    Posts
    24
    Vote Rating
    0
    usiw is on a distinguished road

      0  

    Default [FIXED] [3.0rc1.1] hbox layout messing with form fields heights

    [FIXED] [3.0rc1.1] hbox layout messing with form fields heights


    I am trying to achieve a flex based horizontal layout of fields and hbox is giving me issues. Here is what I am trying to achieve:
    Code:
    +-FormPanel-----------------------------------------+
    |                                                   |
    |  +-FieldSet-(hbox layout)----------------------+  |
    |  |                                             |  |
    |  |  TextField#1 [       ] TextField#2 [      ] |  |
    |  |                                             |  |
    |  +---------------------------------------------+  |
    |                                                   |
    +---------------------------------------------------+
    But what happens is the text fields inside the FieldSet show up as only a pixel or two high. I don't want to set the height as that is always an ugly workaround. Using a column layout resolves the issue but hbox should produce nearly identical results, just without the hassle of setting percentages. Here is the sample code:

    Code:
        var viewport = new Ext.Viewport({
            items: {
                xtype: 'form',                    
                items: [{
                    xtype: 'fieldset',
                    title: 'Fieldset',                        
                    layout: 'hbox',
                    defaults: {
                        layout: 'form',
                        defaultType: 'textfield'                            
                    },
                    items: [{
                        flex: 1,
                        items: {
                            fieldLabel: 'Field 1'
                        }
                    }, {
                        flex: 1,
                        items: {
                            fieldLabel: 'Field 2'
                        }
                    }, {
                        flex: 1,
                        items: {                                    
                            fieldLabel: 'Field 3'
                        }                                
                    }]
                    
                }]
            }
        });
    Is this possibly a bug?
    Last edited by usiw; 9 May 2009 at 5:54 AM. Reason: fixed diagram

  2. #2
    Software Architect
    Join Date
    Sep 2007
    Posts
    13,971
    Vote Rating
    132
    sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light

      0  

    Default


    Setting the height is not a ugly workaround. It is needed. hbox and vbox are absolute positioning layouts.

  3. #3
    Sencha User
    Join Date
    Aug 2008
    Location
    Minnesota
    Posts
    24
    Vote Rating
    0
    usiw is on a distinguished road

      0  

    Default


    Once I resize the browser window and the panels refresh their layout it appears correct, or if I have the example in a tab and navigate away then back to the tab it appears correct. It appears that only on the first layout after render it has issues.

  4. #4
    Sencha User
    Join Date
    Aug 2008
    Location
    Minnesota
    Posts
    24
    Vote Rating
    0
    usiw is on a distinguished road

      0  

    Default


    From the conference it was explained that hbox is an easier-to-work-with column layout with advanced features (stretching, etc) and should produce the same result as :
    Code:
        var viewport = new Ext.Viewport({
            items: {
                xtype: 'form',                    
                items: [{
                    xtype: 'fieldset',
                    title: 'Fieldset',                        
                    layout: 'column',
                    defaults: {
                        layout: 'form',
                        defaultType: 'textfield'                            
                    },
                    items: [{
                        columnWidth: 1/3,
                        items: {
                            fieldLabel: 'Field 1'
                        }
                    }, {
                        columnWidth: 1/3,
                        items: {
                            fieldLabel: 'Field 2'
                        }
                    }, {
                        columnWidth: 1/3,
                        items: {                                    
                            fieldLabel: 'Field 3'
                        }                                
                    }]
                    
                }]
            }
        });
    Maybe there is some confusion on the functionality since the documentation for 3.0 is still largely incomplete, at least in regards to the new features.

  5. #5
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    83
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    Yes, it would seem that this is a bug.

    HBoxLayout should be calculating the height AFTER setting the width.

    Here is a patch:
    Code:
    Ext.override(Ext.layout.HBoxLayout, {
        onLayout : function(ct, target){
            Ext.layout.HBoxLayout.superclass.onLayout.call(this, ct, target);
            var cs = ct.items.items, len = cs.length, c, i, last = len-1, cm;
            var size = this.getTargetSize(target);
            var w = size.width - target.getPadding('lr') - this.scrollOffset,
                h = size.height - target.getPadding('tb'),
                l = this.padding.left, t = this.padding.top;
            if ((Ext.isIE && !Ext.isStrict) && (w < 1 || h < 1)) {
                return;
            } else if (w < 1 && h < 1) {
                return;
            }
            var totalFlex = 0,
                totalWidth = 0;
            for(i = 0; i < len; i++){
                c = cs[i];
                cm = c.margins;
                totalFlex += c.flex || 0;
                totalWidth += c.getWidth() + cm.left + cm.right;
            }
            var extraWidth = w - totalWidth - this.padding.left - this.padding.right,
                allocated = 0,
                cw;
            if(this.pack == 'center'){
                l += extraWidth ? extraWidth/2 : 0;
            }else if(this.pack == 'end'){
                l += extraWidth;
            }
            for(i = 0; i < len; i++){
                c = cs[i];
                cm = c.margins;
                cw = c.getWidth();
                l += cm.left;
                c.setPosition(l, t + cm.top);
                if(this.pack == 'start' && c.flex){
                    var ratio = c.flex/totalFlex;
                    var add = Math.floor(extraWidth*ratio);
                    allocated += add;
                    if(i == last){
                        add += (extraWidth-allocated);
                    }
                    cw += add;
                    c.setWidth(cw);
                }
                l += cw + cm.right;
            }
            var stretchHeight = h - (this.padding.top + this.padding.bottom),
                maxHeight = 0;
            for(i = 0; i < len; i++){
                c = cs[i];
                cm = c.margins;
                maxHeight = Math.max(maxHeight, c.getHeight() + cm.top + cm.bottom);
            }
            var innerCtHeight = maxHeight + this.padding.top + this.padding.bottom;
            switch(this.align){
                case 'stretch':
                    this.innerCt.setSize(w, h);
                    break;
                case 'stretchmax':
                case 'top':
                    this.innerCt.setSize(w, innerCtHeight);
                    break;
                case 'middle':
                    this.innerCt.setSize(w, h = Math.max(h, innerCtHeight));
                    break;
            }
            var availableHeight = h - this.padding.top - this.padding.bottom;
            for(i = 0; i < len; i++){
                c = cs[i];
                if(this.align == 'middle'){
                    var diff = availableHeight - (c.getHeight() + cm.top + cm.bottom);
                    if(diff > 0){
                        c.setPosition(c.x, t + cm.top + (diff/2));
                    }
                }else if(this.align == 'stretch'){
                    c.setHeight((stretchHeight - (cm.top + cm.bottom)).constrain(
                        c.minHeight || 0, c.maxHeight || 1000000));
                }else if(this.align == 'stretchmax'){
                    c.setHeight((maxHeight - (cm.top + cm.bottom)).constrain(
                        c.minHeight || 0, c.maxHeight || 1000000));
                }
            }
        }
    });
    (and the same is true for VBoxLayout, but with width and height reversed)

    ps. This patch will show a quick flicker while doing a layout with align:'center' (child items are first positioned at the top and moved to the center when the height is known).

  6. #6
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,648
    Vote Rating
    583
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    Committed this change and the associated one for vbox.
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

Thread Participants: 3