Results 1 to 10 of 21

Thread: Ext.FloatLayout A layout which floats the child Components

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,607
    Vote Rating
    59
      0  

    Default Ext.FloatLayout A layout which floats the child Components

    This layout floats each child item across its available width.

    Like qooxdoo's Flow layout: http://demo.qooxdoo.org/current/demo...yout~Flow.html

    When the next item won't fit in the width, it explicitly styles it with clear: left so that it wraps to position zero which would not happen if just naturally floated.

    Code:
    Ext.layout.FloatLayout = Ext.extend(Ext.layout.ContainerLayout, {
        setContainer: function(ct) {
            Ext.layout.FloatLayout.superclass.setContainer.apply(this, arguments);
            ct.addClass('ux-float-layout-ct');
        },
    
        renderAll: function(ct) {
            this.cr = this.container.getLayoutTarget().getBox(true).right;
            Ext.layout.FloatLayout.superclass.renderAll.apply(this, arguments);
        },
    
        renderItem : function(c, position, target){
            var r = c.rendered,
                e, p, pe, w;
            Ext.layout.FloatLayout.superclass.renderItem.apply(this, arguments);
            e = c.getDomPositionEl();
            if (!r) {
                e.setStyle('float', 'left');
            }
            e.setStyle('clear', 'none');
            w = e.getWidth() + e.getMargins('lr');
            if (p = c.previousSibling()) {
                pe = p.getDomPositionEl();
                if ((pe.getBox().right + pe.getMargins('r') + w) > this.cr) {
                    e.setStyle('clear', 'left');
                }
            }
        },
    
        isValidParent: function() {
            return false;
        }
    });
    Ext.Container.LAYOUTS['float'] = Ext.layout.FloatLayout;


    Post #4 contains correct layout embedded in an example page.

  2. #2
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    118
      1  

    Default

    ColumnLayout is already a floating layout (simply don't specify a columnWidth).

  3. #3
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,607
    Vote Rating
    59
      0  

    Default

    It won't clear items though if you want a layout like http://blog.mozilla.com/webdev/2009/...-inline-block/

  4. #4
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,607
    Vote Rating
    59
      0  

    Default

    To see this, run this example page in examples/menu

    Code:
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Toolbar with Menus</title>
    <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
    <script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="../../ext-all-debug.js"></script>
    <script type="text/javascript" src="../ux/FieldLabeler.js"></script>
    <script type="text/javascript" src="../form/states.js"></script>
    <style type="text/css">
    .ux-float-layout-ct {
        position: relative;
    }
    .ux-float-layout-ct .ux-float-layout-sizer {
        background: transparent none;
        border: 0 none;
        padding: 0;
        margin: 0;
        width: 0;
    }
    
    .ux-float-layout-ct .x-box-item {
        position: absolute;
    }
    
    .test-item {
        height: 77px;
        width: 60px;
    }
    
    .show-icons .test-item-inner {
        margin-left: 5px;
        margin-top: 5px;
        background-image: url(http://demo.qooxdoo.org/current/demobrowser/resource/qx/icon/Tango/48/devices/computer.png);
        height:48px;
        width:48px;
    }
    
    .hide-icons .test-item {
        border: 1px solid #99BBE8;
        height: auto;
        margin: 3px;
        padding: 2px 4px;
        width: 40px;
    }
    
    .test-item-desc {
        margin-top: 5px;
        text-align: center;
    }
    
    .x-btn-text-icon em {
        display: block;
        height: 100%;
    }
    
    button.test-button {
        height: 100%!important;
        width: 100%!important;
        background-image: url(http://demo.qooxdoo.org/current/demobrowser/resource/qx/icon/Tango/48/devices/computer.png)!important;
        padding-left: 40px!important;
    }
    
    </style>
    <script type="text/javascript">
    Ext.override(Ext.Element, (function(){
        var pxMatch = /(\d+\.?\d+)px/;
    
        return {
            // private.
            // Return the addressable area of the element using explicit CSS style in preference to offsetHeight/offsetWidth.
            // Optionally subtract padding if contentBox parameter is truthy
            getStyleSize : function(contentBox){
                var doc = document,
                    me = this,
                    d = me.dom,
                    extdom = Ext.lib.Dom,
                    isDoc = (d == doc || d == doc.body),
                    isBB, w, h, tbBorder = 0, lrBorder = 0,
                    tbPadding = 0, lrPadding = 0;
                if (isDoc) {
                    return { width: extdom.getViewWidth(), height: extdom.getViewHeight() };
                }
                isBB = me.isBorderBox();
                tbBorder = me.getBorderWidth('tb');
                lrBorder = me.getBorderWidth('lr');
                tbPadding = me.getPadding('tb');
                lrPadding = me.getPadding('lr');
    
                // Width calcs
                // Try the style first, then offsetWidth
                if (w = me.getStyle('width').match(pxMatch)){
                    if ((w = parseFloat(w[1])) && isBB){
                        // Style includes the padding and border if isBB
                        w -= (lrBorder + lrPadding);
                    }
                    w += lrPadding;
                } else if (w = d.offsetWidth){
                    w -= lrBorder;
                }
                w && contentBox && (w -= lrPadding);
    
                // Height calcs
                // Try the style first, then offsetHeight
                if (h = me.getStyle('height').match(pxMatch)){
                    if ((h = parseFloat(h[1])) && isBB){
                        // Style includes the padding and border if isBB
                        h -= (tbBorder + tbPadding);
                    }
                    h += tbPadding;
                } else if (h = d.offsetHeight){
                    h -= tbBorder;
                }
                h && contentBox && (h -= tbPadding);
    
                return {
                    width : w,
                    height : h
                };
            },
    
            /**
             * <p>Returns the dimensions of the element available to lay content out in.<p>
             * <p>If the element (or any ancestor element) has CSS style <code>display : none</code>, the dimensions will be zero.</p>
             * example:<pre><code>
            var vpSize = Ext.getBody().getViewSize();
    
            // all Windows created afterwards will have a default value of 90% height and 95% width
            Ext.Window.override({
                width: vpSize.width * 0.9,
                height: vpSize.height * 0.95
            });
            // To handle window resizing you would have to hook onto onWindowResize.
            </code></pre>
             * @param {Boolean} contentBox True to return the W3 content box <i>within</i> the padding area of the element. False
             * or omitted to return the full area of the element within the border. See <a href="http://www.w3.org/TR/CSS2/box.html">http://www.w3.org/TR/CSS2/box.html</a>
             * @return {Object} An object containing the elements's area: <code>{width: &lt;element width>, height: &lt;element height>}</code>
             */
            getViewSize : function(contentBox){
                var doc = document,
                    me = this,
                    d = me.dom,
                    extdom = Ext.lib.Dom,
                    isDoc = (d == doc || d == doc.body),
                    ss = Ext.isIE ? me.getStyleSize(contentBox) : null, w, h;
                if (isDoc) {
                    return { width: extdom.getViewWidth(), height: extdom.getViewHeight() };
                }
    
                // Width calcs
                // Try clientWidth, then styleWidth
                if (w = d.clientWidth){
    
    //              IE sometimes overestimates client size
                    Ext.isIE && w > ss.width && (w = ss.width);
    
                    if (contentBox){
                        w -= me.getPadding('lr');
                    }
                } else {
                    if (!ss) ss = me.getStyleSize(contentBox);
                    w = ss.width;
                }
    
                // Height calcs
                // Try clientHeight, then styleHeight
                if (h = d.clientHeight){
    
    //              IE sometimes overestimates client size
                    Ext.isIE && h > ss.height && (h = ss.height);
                    if (contentBox){
                        h -= me.getPadding('tb');
                    }
                } else {
                    if (!ss) ss = me.getStyleSize(contentBox);
                    h = ss.height;
                }
    
                return {
                    width : w,
                    height : h
                };
            }
        };
    })());
    
    /**
     * @class Ext.layout.FloatLayout
     * @extends Ext.layout.BoxLayout
     * <p>A layout that arranges items in a left to right flow similar to using HTML's <code>float: left</code> style.</p>
     * <p>When a Component's width (including its padding) won't fit within the available width of the Container (within its padding)
     * then the Component is wrapped to the beginning of a new line, clearing the tallest item on the current line.</p>
     * <p>Items may be vertically aligned with the row they happen to fall within. A line's height is the height of its tallest child
     * item (including its margins), and vertical alignment take place within this space. Vertical alignment is specified for the layout using the
     * {@link #verticalAlign} config, and may be overriden for a single item by configuring an item with a verticalAlign value.</p>
     * <p>Row content may be aligned within the available width of the Container using the {@link #horizontalAlign} config.</p>
     * <p>Child items may be cleared left or right by configuring a <b>clear</b> value in the item.</p>
     * <p>Row and column spacing may be specified using the {@link #verticalSpacing} and {@link #horizontalSpacing} options.</p>
     * <p>Child items may use <code>columnWidth</code> config to specify a fraction of the available width that the item is to occupy.</p>
     */
    Ext.layout.FloatLayout = Ext.extend(Ext.layout.BoxLayout, {
        /**
         * @cfg {Boolean} animate
         * <p><code>true</code> to animate child items into their calculated positions.</p>
         * <p>Defaults to <code>false</code>.</p>
         */
    
        /**
         * @cfg {String} verticalAlign
         * <p>Vertical alignment of child items within each row. Defaults to 'middle'. Values may be</p>
         * <code>'top'</code>, <code>'middle'</code> or <code>'bottom'</code>
         * <p>May be overriden by an individual child item.</p>
         */
        verticalAlign: 'middle',
    
        /**
         * @cfg {String} horizontalAlign
         * <p>Horizontal alignment of child items within each row. Defaults to 'left'. Values may be</p>
         * <code>'left'</code>, <code>'center'</code>, <code>'right'</code> or <code>'justify'</code>
         * <p>May be overriden by an individual child item.</p>
         */
        horizontalAlign: 'left',
    
        /**
         * @cfg {Number} horizontalSpacing
         * <p>Horizontal space to leave between items.</p>
         */
        horizontalSpacing: 0,
    
        /**
         * @cfg {Number} verticalSpacing
         * <p>Vertical space to leave between rows.</p>
         */
        verticalSpacing: 0,
    
        /**
         * @cfg {Number} rightLimit
         * <p>Max rightmost point to which the right edge of items are allowed to reach before wrapping.</p>
         */
        rightLimit: 0,
    
        targetCls : 'ux-float-layout-ct',
    
        setContainer: function(ct) {
            var ce = ct.getLayoutTarget();
            this.sizer = ce.insertFirst({
                cls: 'ux-float-layout-sizer'
            });
            this.padding = this.parseMargins(this.padding||'0');
            Ext.layout.FloatLayout.superclass.setContainer.apply(this, arguments);
        },
    
        renderAll : function(ct, target){
            Ext.layout.BoxLayout.superclass.renderAll.apply(this, arguments);
        },
    
        onLayout: function() {
            var ct = this.container,
                cte = ct.getLayoutTarget(),
                s = cte.getStyleSize(),
                padding = Ext.apply({}, this.padding);
    
            padding.top = this.getMarginValue(this.padding.top, s.height);
            padding.right = this.getMarginValue(this.padding.right, s.width) - this.horizontalSpacing;
            padding.bottom = this.getMarginValue(this.padding.bottom, s.height) - this.verticalSpacing;
            padding.left = this.getMarginValue(this.padding.left, s.width);
    
            var paddingLeft = padding.left + cte.getPadding('l'),
                paddingTop = padding.top + cte.getPadding('t'),
                rightLimit = s.width -= (padding.right + cte.getPadding('r')),
                bottomLimit = s.height - (padding.bottom + cte.getPadding('b')),
                rowStart = 0,
                rowHeight = 0,
                rowWidth = 0,
                x = paddingLeft,
                y = paddingTop,
                items = this.getRenderedItems(ct),
                l = items.length, i, c, lc, ce, cs, m, rm, r,
                itemPos = [], firstFillItem;
    
    //      We never want to see horizontal scroll bars if possible
            cte.setStyle('overflow-x', 'hidden');
    
    //      Content Width.
            s.width -= paddingLeft;
    
            if (this.rightLimit && this.rightLimit < rightLimit) {
                rightLimit = this.rightLimit;
            }
    
            for (var i = 0, l = items.length; i < l; i++) {
                c = items[i];
                ce = c.getPositionEl();
    
    //          Capure first fill item
                if (c.fillHeight) {
                    c.setHeight('auto');
                    if (!firstFillItem) {
                        firstFillItem = i;
                    }
                }
                cs = c.getSize();
    
    //          Allow floating point allocation of available width
                if (c.columnWidth) {
                    c.setWidth(cs.width = (Math.round(s.width * c.columnWidth) - this.horizontalSpacing));
                }
                if (c.cellHeight) {
                    c.setHeight(cs.height = (Math.round(s.height * c.cellHeight) - this.verticalSpacing));
                }
    
                rm = ce.getMargins('r');
                cs.width += ce.getMargins('lr');
                cs.height += ce.getMargins('tb');
                m = c.margins;
                x += m.left;
                r = x + cs.width;
    
    //          This item won't fit on the row.
                if ((r > rightLimit) || (c.clear == 'left') || (lc && lc.clear == 'right')) {
                    this.adjustRow(items, itemPos, rowStart, i - 1, rowHeight, rowWidth, s.width);
                    x = paddingLeft + m.left;
                    y += rowHeight + this.verticalSpacing;
                    r = x + cs.width + m.right;
                    rowStart = i;
                    rowHeight = 0;
                    rowWidth = 0;
                }
    
                rowHeight = Math.max(rowHeight, cs.height);
                rowWidth += cs.width;
    
    //          We are laying out an autoScroll Container, and this item is going to cause a vertical scrollbar:
    //          Adjust the right padding to account for that scrollbar, and reflow.
                if (ct.autoScroll && !this.reflow && ((y + rowHeight) > bottomLimit)) {
                    r = this.padding.right;
                    this.padding.right += Ext.getScrollBarWidth();
                    this.reflow = true;
                    this.onLayout();
                    delete this.reflow;
                    this.padding.right = r;
                    return;
                }
    
                itemPos.push([x, y]);
                x += cs.width + m.right + this.horizontalSpacing;
                lc = c;
            }
    
    //      Adjust the last row
            this.adjustRow(items, itemPos, rowStart, i - 1, rowHeight, rowWidth, s.width);
    
    //      Stretch the container heightwise.
            this.sizer.setHeight(r = (y + rowHeight - cte.getPadding('t')));
    
            if (firstFillItem) {
                var spare = s.height - r - padding.bottom - padding.top;
                rowHeight = 0;
                for (i = firstFillItem; i < items.length && itemPos[i][1] == itemPos[firstFillItem][1]; i++) {
                    c = items[i];
                    ce = c.getPositionEl();
                    cs = c.getSize();
                    cs.height += ce.getMargins('tb');
                    rowHeight = Math.max(rowHeight, cs.height);
                }
                rowHeight += spare;
                for (i = firstFillItem; i < items.length && itemPos[i][1] == itemPos[firstFillItem][1]; i++) {
                    c = items[i];
                    if (c.fillHeight) {
                        ce = c.getPositionEl();
                        cs = c.getSize();
                        c.setHeight(rowHeight - ce.getMargins('tb'));
                    }
                }
            } else {
            }
    
    //      Animate child items into place.
            for (var i = 0, l = items.length; i < l; i++) {
                if (this.animate) {
                    Ext.lib.Anim.motion(items[i].getPositionEl().dom, {left: {to: itemPos[i][0]}, top: {to: itemPos[i][1]}}).animate();
                } else {
                    items[i].setPosition(itemPos[i]);
                }
            }
        },
    
        getMarginValue: function(v, s) {
            if (Ext.isNumber(v)) {
                return (v < 1) ? s * v  : v;
            }
            return 0;
        },
    
        parseMargins : function(v){
            if(Ext.isNumber(v)){
                v = v.toString();
            }
            var ms = v.split(' ');
            var len = ms.length;
            if(len == 1){
                ms[1] = ms[2] = ms[3] = ms[0];
            } else if(len == 2){
                ms[2] = ms[0];
                ms[3] = ms[1];
            } else if(len == 3){
                ms[3] = ms[1];
            }
            return {
                top: parseFloat(ms[0], 10) || 0,
                right: parseFloat(ms[1], 10) || 0,
                bottom: parseFloat(ms[2], 10) || 0,
                left: parseFloat(ms[3], 10) || 0
            };
        },
    
    //  Adjust vertical alignment within row.
    //  Adjust horizontal alignment if required.
        adjustRow: function(items, itemPos, rowStart, rowEnd, rowHeight, rowWidth, availWidth) {
            var i, c, h, j = 0, gaps = rowEnd - rowStart, spareWidth, alignmentIncrement = 0;
            rowWidth += gaps * this.horizontalSpacing;
            spareWidth = availWidth - rowWidth;
    
            switch (this.horizontalAlign) {
                case 'middle':
                case 'center':
                    alignmentIncrement = Math.max(spareWidth / 2, 0);
                    break;
                case 'right':
                    alignmentIncrement = Math.max(spareWidth, 0);
                    break;
                case 'justify':
                    if (gaps) {
                        j = Math.max(spareWidth / gaps, 0);
                    }
            }
    
            for (i = rowStart; i <= rowEnd; i++) {
                c = items[i];
                h = c.getHeight() + c.getPositionEl().getMargins('tb');
                itemPos[i][0] += alignmentIncrement;
                alignmentIncrement += j;
                switch (c.verticalAlign || this.verticalAlign) {
                    case 'middle':
                    case 'center':
                        itemPos[i][1] += (rowHeight - h) / 2;
                        break;
                    case 'bottom':
                        itemPos[i][1] += (rowHeight - h);
                }
            }
        },
    
        isValidParent: function(c, e) {
            return c.getPositionEl().dom.parentNode === e.dom;
        }
    });
    Ext.Container.LAYOUTS['float'] = Ext.layout.FloatLayout;
    
    Ext.override(Ext.Element, {
    
    /**
     * Lay out the child elements of this element in a left to right flow similar to using HTML's <code>float: left</code> style.</p>
     * <p>When a Component's width (including its padding) won't fit within the available width of the Container (within its padding)
     * then the Component is wrapped to the beginning of a new line, clearing the tallest item on the current line.</p>
     * <p>Items may be vertically aligned with the row they happen to fall within. A line's height is the height of its tallest child
     * item (including its margins), and vertical alignment take place within this space. Vertical alignment is specified for the layout using the
     * {@link #verticalAlign} config, and may be overriden for a single item by configuring an item with a verticalAlign value.</p>
     * <p>Row content may be aligned within the available width of the Container using the {@link #horizontalAlign} config.</p>
     * <p>Child items may be cleared left or right by configuring a <b>clear</b> value in the item.</p>
     * <p>Row and column spacing may be specified using the {@link #verticalSpacing} and {@link #horizontalSpacing} options.
     */
        doLayout: function(config) {
            this.layout = Ext.apply({
                itemSelector: '/*:not(.ux-float-layout-sizer)',
                animate: false,
                verticalAlign: 'middle',
                horizontalAlign: 'left',
                horizontalSpacing: 0,
                verticalSpacing: 0,
                padding: 0
            }, config);
            this.layout.padding = Ext.layout.ContainerLayout.prototype.parseMargins(this.layout.padding);
    
            var items = this.query(this.layout.itemSelector),
                me = this,
                paddingLeft = this.layout.padding.left + me.getPadding('l'),
                paddingTop = this.layout.padding.top + me.getPadding('t'),
                s = me.getStyleSize(),
                rightLimit = (s.width -= (this.layout.padding.right + me.getPadding('r'))),
                bottomLimit = s.height - (this.layout.padding.bottom + me.getPadding('b')),
                rowStart = 0,
                rowHeight = 0,
                rowWidth = 0,
                x = paddingLeft,
                y = paddingTop,
                l = items.length, i, c, cs, m, r,
                itemPos = [], a;
    
    //      Nothing to lay out.
            if (!items.length) return;
    
            if (!(me.sizer = this.child('.ux-float-layout-sizer'))) {
                me.sizer = me.insertFirst({
                    cls: 'ux-float-layout-sizer'
                });
            }
    
    //      We never want to see horizontal scroll bars if possible
            me.setStyle({
                'overflow-x': 'hidden',
                position: 'relative'
            });
    
    //      Content Width.
            s.width -= paddingLeft;
    
            for (var i = 0, l = items.length; i < l; i++) {
                c = (items[i] = Ext.get(items[i]));
                c.setStyle({
                    position: 'absolute'
                });
                cs = c.getSize();
                m = /*c.margins ||*/ {top: 0, right: 0, bottom: 0, left: 0};
                cs.width += c.getMargins('lr');
                cs.height += c.getMargins('tb');
                r = x + m.left + cs.width + m.right;
    
    //          This item won't fit on the row.
                if ((r > rightLimit) || (c.dom.style.clear == 'left') || ((i > 0) && items[i - 1].dom.style.clear == 'right')) {
                    me.adjustRow(items, itemPos, rowStart, i - 1, rowHeight, rowWidth, s.width);
                    x = paddingLeft;
                    y += rowHeight + me.layout.verticalSpacing;
                    r = x + m.left + cs.width + m.right;
                    rowStart = i;
                    rowHeight = 0;
                    rowWidth = 0;
                }
    
                rowHeight = Math.max(rowHeight, cs.height);
                rowWidth += cs.width;
    
    //          This item is going to cause a vertical scrollbar:
    //          Adjust the right padding to account for that scrollbar, and reflow.
                if (!me.reflow && ((y + rowHeight) > bottomLimit)) {
                    r = me.layout.padding.right;
                    me.layout.padding.right += Ext.getScrollBarWidth();
                    me.reflow = true;
                    me.doLayout();
                    delete me.reflow;
                    me.layout.padding.right = r;
                    return;
                }
    
                itemPos.push([x, y]);
                x = r + me.layout.horizontalSpacing;
            }
    
    //      Adjust the last row
            me.adjustRow(items, itemPos, rowStart, i - 1, rowHeight, rowWidth, s.width);
    
    //      Stretch the container heightwise.
            me.sizer.setHeight(y + rowHeight - paddingTop);
    
    //      Animate child items into place.
            for (var i = 0, l = items.length; i < l; i++) {
                if (me.layout.animate) {
                    a = Ext.lib.Anim.motion(items[i].dom, {left: {to: itemPos[i][0]}, top: {to: itemPos[i][1]}});
                    a.animate();
                } else {
                    items[i].setStyle({
                        left: itemPos[i][0] + 'px',
                        top: itemPos[i][1] + 'px'
                    });
                }
            }
        },
    
    //  Adjust vertical alignment within row.
    //  Adjust horizontal alignment if required.
        adjustRow: function(items, itemPos, rowStart, rowEnd, rowHeight, rowWidth, availWidth) {
            var me = this, i, c, h, j = 0, gaps = rowEnd - rowStart, spareWidth, alignmentIncrement = 0;
            rowWidth += gaps * me.layout.horizontalSpacing;
            spareWidth = availWidth - rowWidth;
    
            switch (me.layout.horizontalAlign) {
                case 'middle':
                case 'center':
                    alignmentIncrement = Math.max(spareWidth / 2, 0);
                    break;
                case 'right':
                    alignmentIncrement = Math.max(spareWidth, 0);
                    break;
                case 'justify':
                    if (gaps) {
                        j = Math.max(spareWidth / gaps, 0);
                    }
            }
    
            for (i = rowStart; i <= rowEnd; i++) {
                c = items[i];
                h = c.getHeight() + c.getMargins('tb');
                itemPos[i][0] += alignmentIncrement;
                alignmentIncrement += j;
                switch (c.dom.style.verticalAlign || me.layout.verticalAlign) {
                    case 'middle':
                    case 'center':
                        itemPos[i][1] += (rowHeight - h) / 2;
                        break;
                    case 'bottom':
                        itemPos[i][1] += (rowHeight - h);
                }
            }
        }
    });
    
    Ext.onReady(function(){
        Ext.QuickTips.init();
    
        // Menus can be prebuilt and passed by reference
        var dateMenu = new Ext.menu.DateMenu({
            handler: function(dp, date){
                Ext.example.msg('Date Selected', 'You chose {0}.', date.format('M j, Y'));
            }
        });
    
        var colorMenu = new Ext.menu.ColorMenu({
            handler: function(cm, color){
                Ext.example.msg('Color Selected', 'You chose {0}.', color);
            }
        });
        
        var store = new Ext.data.ArrayStore({
            fields: ['abbr', 'state'],
            data : Ext.exampledata.states // from states.js
        });
    
        var combo = new Ext.form.ComboBox({
            store: store,
            displayField: 'state',
            typeAhead: true,
            mode: 'local',
            triggerAction: 'all',
            emptyText: 'Select a state...',
            selectOnFocus: true,
            width: 135,
            getListParent: function() {
                return this.el.up('.x-menu');
            },
            iconCls: 'no-icon'
        });
    
        var menu = new Ext.menu.Menu({
            id: 'mainMenu',
            style: {
                overflow: 'visible'     // For the Combo popup
            },
            items: [
                combo,                  // A Field in a Menu
                {
                    text: 'I like Ext',
                    checked: true,       // when checked has a boolean value, it is assumed to be a CheckItem
                    checkHandler: onItemCheck
                }, '-', {
                    text: 'Radio Options',
                    menu: {        // <-- submenu by nested config object
                        items: [
                            // stick any markup in a menu
                            '<b class="menu-title">Choose a Theme</b>',
                            {
                                text: 'Aero Glass',
                                checked: true,
                                group: 'theme',
                                checkHandler: onItemCheck
                            }, {
                                text: 'Vista Black',
                                checked: false,
                                group: 'theme',
                                checkHandler: onItemCheck
                            }, {
                                text: 'Gray Theme',
                                checked: false,
                                group: 'theme',
                                checkHandler: onItemCheck
                            }, {
                                text: 'Default Theme',
                                checked: false,
                                group: 'theme',
                                checkHandler: onItemCheck
                            }
                        ]
                    }
                },{
                    text: 'Choose a Date',
                    iconCls: 'calendar',
                    menu: dateMenu // <-- submenu by reference
                },{
                    text: 'Choose a Color',
                    menu: colorMenu // <-- submenu by reference
                }
            ]
        });
    
        var tb = new Ext.Toolbar({
            id: 'tb',
            layout: {
                type: 'float',
                verticalSpacing: 4,
                horizontalSpacing: 4
            }
        });
    
        tb.add({
                text:'Button w/ Menu',
                iconCls: 'bmenu',  // <-- icon
                menu: menu  // assign menu by instance
            }, {
                text: 'Users',
                iconCls: 'user',
                menu: {
                    xtype: 'menu',
                    plain: true,
                    items: {
                        xtype: 'buttongroup',
                        title: 'User options',
                        autoWidth: true,
                        columns: 2,
                        defaults: {
                            xtype: 'button',
                            scale: 'large',
                            width: '100%',
                            iconAlign: 'left'
                        },
                        items: [{
                            text: 'User<br/>manager',
                            iconCls: 'edit'
                        },{
                            iconCls: 'add',
                            width: 'auto',
                            tooltip: 'Add user'
                        },{
                            colspan: 2,
                            text: 'Import',
                            scale: 'small'
                        },{
                            colspan: 2,
                            text: 'Who is online?',
                            scale: 'small'
                        }]
                    }
                }
            },
            new Ext.Toolbar.SplitButton({
                text: 'Split Button',
                handler: onButtonClick,
                tooltip: {text:'This is a an example QuickTip for a toolbar item', title:'Tip Title'},
                iconCls: 'blist',
                // Menus can be built/referenced by using nested menu config objects
                menu : {
                    items: [{
                        text: '<b>Bold</b>', handler: onItemClick
                    }, {
                        text: '<i>Italic</i>', handler: onItemClick
                    }, {
                        text: '<u>Underline</u>', handler: onItemClick
                    }, '-', {
                        text: 'Pick a Color',
                        handler: onItemClick,
                        menu: {
                            items: [
                                new Ext.ColorPalette({
                                    listeners: {
                                        select: function(cp, color){
                                            Ext.example.msg('Color Selected', 'You chose {0}.', color);
                                        }
                                    }
                                }), '-',
                                {
                                    text: 'More Colors...',
                                    handler: onItemClick
                                }
                            ]
                        }
                    }, {
                        text: 'Extellent!',
                        handler: onItemClick
                    }]
                }
            }), '-', {
            text: 'Toggle Me',
            enableToggle: true,
            toggleHandler: onItemToggle,
            pressed: true
        });
    
        menu.addSeparator();
        // Menus have a rich api for
        // adding and removing elements dynamically
        var item = menu.add({
            text: 'Dynamically added Item'
        });
        // items support full Observable API
        item.on('click', onItemClick);
    
        // items can easily be looked up
        menu.add({
            text: 'Disabled Item',
            id: 'disableMe'  // <-- Items can also have an id for easy lookup
            // disabled: true   <-- allowed but for sake of example we use long way below
        });
        // access items by id or index
        menu.items.get('disableMe').disable();
    
        // They can also be referenced by id in or components
        tb.add('-', {
            icon: 'list-items.gif', // icons can also be specified inline
            cls: 'x-btn-icon',
            tooltip: '<b>Quick Tips</b><br/>Icon only button with tooltip'
        }, '-');
        
        var scrollMenu = new Ext.menu.Menu();
        for (var i = 0; i < 50; ++i){
            scrollMenu.add({
                text: 'Item ' + (i + 1)
            });
        }
        
        tb.add(new Ext.form.TextField());
        
        // scrollable menu
        tb.add({
            scale: 'large',
            icon: 'preview.png',
            cls: 'x-btn-text-icon',
            text: 'Scrolling Menu',
            menu: scrollMenu
        });
        
        // add a combobox to the toolbar
        var combo = new Ext.form.ComboBox({
            store: store,
            displayField: 'state',
            typeAhead: true,
            mode: 'local',
            triggerAction: 'all',
            emptyText:'Select a state...',
            selectOnFocus:true,
            width:135
        });
        tb.addField(combo);
    
        tb.add({
            text: 'Another'
        }, {
            text: 'Yet another'
        }, {
            text: 'Still another'
        }, {
            text: 'The last one!'
        });
    
        // sample static data for the store
        var myData = [
            ['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
            ['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
            ['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am'],
            ['American Express Company',52.55,0.01,0.02,'9/1 12:00am'],
            ['American International Group, Inc.',64.13,0.31,0.49,'9/1 12:00am'],
            ['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am'],
            ['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am'],
            ['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am'],
            ['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am'],
            ['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am'],
            ['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am'],
            ['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am'],
            ['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am'],
            ['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am'],
            ['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am'],
            ['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am'],
            ['International Business Machines',81.41,0.44,0.54,'9/1 12:00am'],
            ['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am'],
            ['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am'],
            ['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am'],
            ['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am'],
            ['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am'],
            ['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am'],
            ['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am'],
            ['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am'],
            ['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am'],
            ['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am'],
            ['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am'],            
            ['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am']
        ];
    
        /**
         * Custom function used for column renderer
         * @param {Object} val
         */
        function change(val){
            if(val > 0){
                return '<span style="color:green;">' + val + '</span>';
            }else if(val < 0){
                return '<span style="color:red;">' + val + '</span>';
            }
            return val;
        }
    
        /**
         * Custom function used for column renderer
         * @param {Object} val
         */
        function pctChange(val){
            if(val > 0){
                return '<span style="color:green;">' + val + '%</span>';
            }else if(val < 0){
                return '<span style="color:red;">' + val + '%</span>';
            }
            return val;
        }
    
        // create the data store
        var store = new Ext.data.ArrayStore({
            fields: [
               {name: 'company'},
               {name: 'price', type: 'float'},
               {name: 'change', type: 'float'},
               {name: 'pctChange', type: 'float'},
               {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
            ]
        });
    
        // manually load local data
        store.loadData(myData);
    
        // create the Grid
        var grid = new Ext.grid.GridPanel({
            store: store,
            columns: [
                {id:'company',header: 'Company', width: 160, sortable: true, dataIndex: 'company'},
                {header: 'Price', width: 75, sortable: true, renderer: 'usMoney', dataIndex: 'price'},
                {header: 'Change', width: 75, sortable: true, renderer: change, dataIndex: 'change'},
                {header: '% Change', width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},
                {header: 'Last Updated', width: 85, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
            ],
            stripeRows: true,
            autoExpandColumn: 'company',
            border: false
        });
    
        new Ext.Window({
            title: 'Test Float Toolbar',
            height: 300,
            width: 600,
            tbar: tb,
            layout: 'fit',
            items: grid
        }).show();
    
        // functions to display feedback
        function onButtonClick(btn){
            Ext.example.msg('Button Click','You clicked the "{0}" button.', btn.text);
        }
    
        function onItemClick(item){
            Ext.example.msg('Menu Click', 'You clicked the "{0}" menu item.', item.text);
        }
    
        function onItemCheck(item, checked){
            Ext.example.msg('Item Check', 'You {1} the "{0}" menu item.', item.text, checked ? 'checked' : 'unchecked');
        }
    
        function onItemToggle(item, pressed){
            Ext.example.msg('Button Toggled', 'Button "{0}" was toggled to {1}.', item.text, pressed);
        }
        
        var it = [];
        for (var i = 0; i < 30; i++) {
            it.push({
                xtype: 'box',
                autoEl: {
                    cls: 'test-item',
                    cn: [{
                        cls: 'test-item-inner'
                    }, {
                        cls: 'test-item-desc',
                        html: 'Item ' + (i + 1)
                    }]
                }
            });
        }
    
        w = new Ext.Window({
            title: 'Flow Layout',
            cls: 'show-icons',
            x: 100,
            y: 100,
            width: 314,
            height: 523,
            autoScroll: true,
            layout: {
                type: 'float',
                rightLimit: 500,
                animate: true
            },
            items: it,
            bbar: {
                xtype: 'container',
                layout: {
                    type: 'float',
                    horizontalAlign: 'justify'
                },
                cls: 'x-toolbar',
                style: {
                    overflow: 'hidden',
                    paddingLeft: 0,
                    paddingRight: 0
                },
                defaultType: 'container',
                defaults: {
                    style: {
                        width: '33%'
                    }
                },
                items: [{
                    layout: {
                        type: 'float',
                        padding: '0 0 0 2'
                    },
                    items: {
                        xtype: 'button',
                        text: 'View icons',
                        enableToggle: true,
                        pressed: true,
                        toggleHandler: function(b, state) {
                            if (state) {
                                w.addClass('show-icons');
                                w.removeClass('hide-icons');
                            } else {
                                w.addClass('hide-icons');
                                w.removeClass('show-icons');
                            }
                            w.doLayout();
                        }
                    }
                }, {
                    layout: {
                     type: 'float',
                        horizontalAlign: 'center'
                    },
                    items: {
                        xtype: 'button',
                        text: 'Centre Button'
                    }
                }, {
                    layout: {
                    type: 'float',
                        horizontalAlign: 'right',
                        padding: '0 2 0 0'
                    },
                    items: {
                        xtype: 'button',
                        text: 'Right Button'
                    }
                }]
            }
        }).show();
    
        it = [];
        it.push({
            xtype: 'button',
            iconCls: 'test-button',
            text: '1. First Button',
            width: 140,
            height: 56
        });
        it.push({
            xtype: 'button',
            iconCls: 'test-button',
            text: '2. Second longer Button...',
            width: 200,
            height: 56,
            clear: 'right'
        });
        it.push({
            xtype: 'button',
            iconCls: 'test-button',
            text: '3. Third really, really long Button',
            width: 240,
            height: 100
        });
        it.push({
            xtype: 'button',
            iconCls: 'test-button',
            text: 'Number 4',
            width: 120,
            height: 56,
            verticalAlign: 'bottom'
        });
        it.push({
            xtype: 'button',
            text: '20px Margins around the great big 5th button!',
            width: 240,
            height: 100,
            clear: 'right',
            style: {
                margin: '20px'
            }
        });
        it.push({
            xtype: 'button',
            iconCls: 'test-button',
            text: 'Number 6',
            width: 120,
            height: 56
        });
        it.push({
            xtype: 'button',
            text: '7th a wide, short button',
            width: 120,
            verticalAlign: 'top'
        });
    
        new Ext.Window({
            title: 'Flow Layout',
            x: 500,
            y: 100,
            width: 500,
            height: 400,
            autoScroll: true,
            layout: {
                type: 'float',
                horizontalAlign: 'center',
                animate: true
            },
            items: it
        }).show();
        
        it = [];
        for (i = 0; i < 10; i++) {
            it.push({
                xtype: 'box',
                columnWidth: 0.25,
                html: 'columnWidth:0.25'
            });
        }
        it[4].cellHeight = 0.5;
        it[4].html += ', cellHeight: 0.5';
        it[5].cellHeight = 0.5;
        it[6].cellHeight = 0.5;
        it[6].html += ', cellHeight: 0.5';
        it[5].columnWidth = 0.5;
        it[5].html = 'columnWidth:0.5, cellHeight: 0.5';
        it[9].columnWidth = 0.5;
        it[9].html = 'columnWidth:0.5';
        it[7].fillHeight = true;
        it[7].html += ',<br>fillHeight: true';
    
        new Ext.Window({
            title: 'A Flow layout window using padding: 0.125',
            height: 400, width: 600,
            minWidth: 530,
            x: 200, y: 55,
            autoScroll: true,
            layout: {
                type: 'float',
                horizontalSpacing: 5,
                verticalSpacing: 5,
                verticalAlign: 'top',
                padding: '5 0.125 5 0.125'
            },
            defaultType: 'box',
            defaults: {
                style: {
                    height: '20px',
                    padding: '5px 0 0 5px',
                    backgroundColor: 'red'
                }
            },
            items: it
        }).show();
    
        it = [];
        for (i = 0; i < 10; i++) {
            it.push({ fieldLabel: 'Form item ' + (i + 1)});
        }
        new Ext.Window({
            title: 'A Flow layout form using columnWidth: 0.5',
            cls: 'the-flow-form',
            height: 400, width: 600,
            autoScroll: true,
            layout: {
                type: 'float',
                horizontalSpacing: 5,
                padding: '5 5 1 5'
            },
            defaultType: 'textfield',
            defaults: {
                plugins: [ Ext.ux.FieldLabeler ],
                columnWidth: 0.5
            },
            items: it
        }).show();
    
    });
    </script>
    <link rel="stylesheet" type="text/css" href="menus.css" />
    <link rel="stylesheet" type="text/css" href="../shared/examples.css" />
    </head>
    <body>
    <h1>FloatLayout Toolbar with Menus</h1>
    <p>The js is inline.</p>
    </body>
    </html>
    Then change it to use layout: 'column', and then in Firebug, type

    Code:
    Ext.getCmp("tb").setWidth(500).doLayout();
    You see it does not wrap properly because of uneven heights of the elements:



    When you do this with layout: 'float', you get


  5. #5
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,607
    Vote Rating
    59
      0  

    Default

    The layout class:

    Code:
    /**
     * @class Ext.layout.FloatLayout
     * @extends Ext.layout.BoxLayout
     * <p>A layout that arranges items in a left to right flow similar to using HTML's <code>float: left</code> style.</p>
     * <p>When a Component's width (including its padding) won't fit within the available width of the Container (within its padding)
     * then the Component is wrapped to the beginning of a new line, clearing the tallest item on the current line.</p>
     * <p>Items may be vertically aligned with the row they happen to fall within. A line's height is the height of its tallest child
     * item (including its margins), and vertical alignment take place within this space. Vertical alignment is specified for the layout using the
     * {@link #verticalAlign} config, and may be overriden for a single item by configuring an item with a verticalAlign value.</p>
     * <p>Row content may be aligned within the available width of the Container using the {@link #horizontalAlign} config.</p>
     * <p>Child items may be cleared left or right by configuring a <b>clear</b> value in the item.</p>
     * <p>Row and column spacing may be specified using the {@link #verticalSpacing} and {@link #horizontalSpacing} options.</p>
     * <p>Child items may use <code>columnWidth</code> config to specify a fraction of the available width that the item is to occupy.</p>
     */
    Ext.layout.FloatLayout = Ext.extend(Ext.layout.BoxLayout, {
        /**
         * @cfg {Boolean} animate
         * <p><code>true</code> to animate child items into their calculated positions.</p>
         * <p>Defaults to <code>false</code>.</p>
         */
    
        /**
         * @cfg {String} verticalAlign
         * <p>Vertical alignment of child items within each row. Defaults to 'middle'. Values may be</p>
         * <code>'top'</code>, <code>'middle'</code> or <code>'bottom'</code>
         * <p>May be overriden by an individual child item.</p>
         */
        verticalAlign: 'middle',
    
        /**
         * @cfg {String} horizontalAlign
         * <p>Horizontal alignment of child items within each row. Defaults to 'left'. Values may be</p>
         * <code>'left'</code>, <code>'center'</code>, <code>'right'</code> or <code>'justify'</code>
         * <p>May be overriden by an individual child item.</p>
         */
        horizontalAlign: 'left',
    
        /**
         * @cfg {Number} horizontalSpacing
         * <p>Horizontal space to leave between items.</p>
         */
        horizontalSpacing: 0,
    
        /**
         * @cfg {Number} verticalSpacing
         * <p>Vertical space to leave between rows.</p>
         */
        verticalSpacing: 0,
    
        /**
         * @cfg {Number} rightLimit
         * <p>Max rightmost point to which the right edge of items are allowed to reach before wrapping.</p>
         */
        rightLimit: 0,
    
        targetCls : 'ux-float-layout-ct',
    
        setContainer: function(ct) {
            var ce = ct.getLayoutTarget();
            this.sizer = ce.insertFirst({
                cls: 'ux-float-layout-sizer'
            });
            this.padding = this.parseMargins(this.padding||'0');
            Ext.layout.FloatLayout.superclass.setContainer.apply(this, arguments);
        },
    
        renderAll : function(ct, target){
            Ext.layout.BoxLayout.superclass.renderAll.apply(this, arguments);
        },
    
        onLayout: function() {
            var ct = this.container,
                cte = ct.getLayoutTarget(),
                s = cte.getStyleSize(),
                padding = Ext.apply({}, this.padding);
    
            padding.top = this.getMarginValue(this.padding.top, s.height);
            padding.right = this.getMarginValue(this.padding.right, s.width) - this.horizontalSpacing;
            padding.bottom = this.getMarginValue(this.padding.bottom, s.height) - this.verticalSpacing;
            padding.left = this.getMarginValue(this.padding.left, s.width);
    
            var paddingLeft = padding.left + cte.getPadding('l'),
                paddingTop = padding.top + cte.getPadding('t'),
                rightLimit = s.width -= (padding.right + cte.getPadding('r')),
                bottomLimit = s.height - (padding.bottom + cte.getPadding('b')),
                rowStart = 0,
                rowHeight = 0,
                rowWidth = 0,
                x = paddingLeft,
                y = paddingTop,
                items = this.getRenderedItems(ct),
                l = items.length, i, c, lc, ce, cs, m, rm, r,
                itemPos = [], firstFillItem;
    
    //      We never want to see horizontal scroll bars if possible
            cte.setStyle('overflow-x', 'hidden');
    
    //      Content Width.
            s.width -= paddingLeft;
    
            if (this.rightLimit && this.rightLimit < rightLimit) {
                rightLimit = this.rightLimit;
            }
    
            for (var i = 0, l = items.length; i < l; i++) {
                c = items[i];
                ce = c.getPositionEl();
    
    //          Capure first fill item
                if (c.fillHeight) {
                    c.setHeight('auto');
                    if (!firstFillItem) {
                        firstFillItem = i;
                    }
                }
                cs = c.getSize();
    
    //          Allow floating point allocation of available width
                if (c.columnWidth) {
                    c.setWidth(cs.width = (Math.round(s.width * c.columnWidth) - this.horizontalSpacing));
                }
                if (c.cellHeight) {
                    c.setHeight(cs.height = (Math.round(s.height * c.cellHeight) - this.verticalSpacing));
                }
    
                rm = ce.getMargins('r');
                cs.width += ce.getMargins('lr');
                cs.height += ce.getMargins('tb');
                m = c.margins;
                x += m.left;
                r = x + cs.width;
    
    //          This item won't fit on the row.
                if ((r > rightLimit) || (c.clear == 'left') || (lc && lc.clear == 'right')) {
                    this.adjustRow(items, itemPos, rowStart, i - 1, rowHeight, rowWidth, s.width);
                    x = paddingLeft + m.left;
                    y += rowHeight + this.verticalSpacing;
                    r = x + cs.width + m.right;
                    rowStart = i;
                    rowHeight = 0;
                    rowWidth = 0;
                }
    
                rowHeight = Math.max(rowHeight, cs.height);
                rowWidth += cs.width;
    
    //          We are laying out an autoScroll Container, and this item is going to cause a vertical scrollbar:
    //          Adjust the right padding to account for that scrollbar, and reflow.
                if (ct.autoScroll && !this.reflow && ((y + rowHeight) > bottomLimit)) {
                    r = this.padding.right;
                    this.padding.right += Ext.getScrollBarWidth();
                    this.reflow = true;
                    this.onLayout();
                    delete this.reflow;
                    this.padding.right = r;
                    return;
                }
    
                itemPos.push([x, y]);
                x += cs.width + m.right + this.horizontalSpacing;
                lc = c;
            }
    
    //      Adjust the last row
            this.adjustRow(items, itemPos, rowStart, i - 1, rowHeight, rowWidth, s.width);
    
    //      Stretch the container heightwise.
            this.sizer.setHeight(r = (y + rowHeight - cte.getPadding('t')));
    
            if (firstFillItem) {
                var spare = s.height - r - padding.bottom - padding.top;
                rowHeight = 0;
                for (i = firstFillItem; i < items.length && itemPos[i][1] == itemPos[firstFillItem][1]; i++) {
                    c = items[i];
                    ce = c.getPositionEl();
                    cs = c.getSize();
                    cs.height += ce.getMargins('tb');
                    rowHeight = Math.max(rowHeight, cs.height);
                }
                rowHeight += spare;
                for (i = firstFillItem; i < items.length && itemPos[i][1] == itemPos[firstFillItem][1]; i++) {
                    c = items[i];
                    if (c.fillHeight) {
                        ce = c.getPositionEl();
                        cs = c.getSize();
                        c.setHeight(rowHeight - ce.getMargins('tb'));
                    }
                }
            } else {
            }
    
    //      Animate child items into place.
            for (var i = 0, l = items.length; i < l; i++) {
                if (this.animate) {
                    Ext.lib.Anim.motion(items[i].getPositionEl().dom, {left: {to: itemPos[i][0]}, top: {to: itemPos[i][1]}}).animate();
                } else {
                    items[i].setPosition(itemPos[i]);
                }
            }
        },
    
        getMarginValue: function(v, s) {
            if (Ext.isNumber(v)) {
                return (v < 1) ? s * v  : v;
            }
            return 0;
        },
    
        parseMargins : function(v){
            if(Ext.isNumber(v)){
                v = v.toString();
            }
            var ms = v.split(' ');
            var len = ms.length;
            if(len == 1){
                ms[1] = ms[2] = ms[3] = ms[0];
            } else if(len == 2){
                ms[2] = ms[0];
                ms[3] = ms[1];
            } else if(len == 3){
                ms[3] = ms[1];
            }
            return {
                top: parseFloat(ms[0], 10) || 0,
                right: parseFloat(ms[1], 10) || 0,
                bottom: parseFloat(ms[2], 10) || 0,
                left: parseFloat(ms[3], 10) || 0
            };
        },
    
    //  Adjust vertical alignment within row.
    //  Adjust horizontal alignment if required.
        adjustRow: function(items, itemPos, rowStart, rowEnd, rowHeight, rowWidth, availWidth) {
            var i, c, h, j = 0, gaps = rowEnd - rowStart, spareWidth, alignmentIncrement = 0;
            rowWidth += gaps * this.horizontalSpacing;
            spareWidth = availWidth - rowWidth;
    
            switch (this.horizontalAlign) {
                case 'middle':
                case 'center':
                    alignmentIncrement = Math.max(spareWidth / 2, 0);
                    break;
                case 'right':
                    alignmentIncrement = Math.max(spareWidth, 0);
                    break;
                case 'justify':
                    if (gaps) {
                        j = Math.max(spareWidth / gaps, 0);
                    }
            }
    
            for (i = rowStart; i <= rowEnd; i++) {
                c = items[i];
                h = c.getHeight() + c.getPositionEl().getMargins('tb');
                itemPos[i][0] += alignmentIncrement;
                alignmentIncrement += j;
                switch (c.verticalAlign || this.verticalAlign) {
                    case 'middle':
                    case 'center':
                        itemPos[i][1] += (rowHeight - h) / 2;
                        break;
                    case 'bottom':
                        itemPos[i][1] += (rowHeight - h);
                }
            }
        },
    
        isValidParent: function(c, e) {
            return c.getPositionEl().dom.parentNode === e.dom;
        }
    });
    Ext.Container.LAYOUTS['float'] = Ext.layout.FloatLayout;
    CSS:

    Code:
    .ux-float-layout-ct {
        position: relative;
    }
    .ux-float-layout-ct .ux-float-layout-sizer {
        background: transparent none;
        border: 0 none;
        padding: 0;
        margin: 0;
        width: 0;
    }
    .ux-float-layout-ct .x-box-item {
    	position: absolute;
    }

  6. #6
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    118
      0  

    Default

    I like the first version better.

    You could also add support for optional float:right and clear:both (based on item config).

  7. #7
    Ext JS Premium Member
    Join Date
    Nov 2009
    Location
    St Louis,MO
    Posts
    267
    Vote Rating
    18
      0  

    Default

    This needs a tweak on onLayout:

    Code:
         onLayout: function() {
             var ct = this.containe,
                 cte = ct.getLayoutTarget(),
                 s = cte.getStyleSize(),
                 padding = Ext.apply({}, this.padding);
     
             this.renderAll(ct, cte);
    Without this line you cannot add components to the container after it is initially rendered.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •