1. #1
    Sencha User lsaffre's Avatar
    Join Date
    Aug 2009
    Location
    Estonia
    Posts
    34
    Vote Rating
    0
    lsaffre is on a distinguished road

      0  

    Default collapsibles in a vbox

    collapsibles in a vbox


    Hello,

    below is a showcase that opens a window with 3 collapsible grids in a vbox. When one of these grids is collapsed, I'd like the other two grids to fill up the space that got free.
    This is not a case for AccordionLayout since more than one Panel can be expanded.
    I guess that with BorderLayout it would work out of the box, but I'd like this to work also with 2 or 4 grids.

    Code:
    <html><head>
    <!--  -->
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title id="title">2010-09-12</title>
    <!-- ** CSS ** -->
    <!-- base library -->
    <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
    <!-- overrides to base library -->
    <!-- ** Javascript ** -->
    <!-- ExtJS library: base/adapter -->
    <script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
    <!-- ExtJS library: all widgets -->
    <script type="text/javascript" src="../../ext-all-debug.js"></script>
    <script type="text/javascript">
    
    // taken from http://examples.extjs.eu/
    ExampleGrid = Ext.extend(Ext.grid.GridPanel, {
      initComponent:function() {
      // hard coded - cannot be changed from outside
      var config = {
        store: new Ext.data.SimpleStore({
          id:0
          ,fields:[
            {name: 'company'}
            ,{name: 'price', type: 'float'}
            ,{name: 'change', type: 'float'}
            ,{name: 'pctChange', type: 'float'}
            ,{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
            ,{name: 'industry'}
            ,{name: 'desc'}
          ]
          ,data:[
            ['3m Co',71.72,0.02,0.03,'8/1 12:00am', 'Manufacturing'],
            ['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am', 'Manufacturing'],
            ['Altria Group Inc',83.81,0.28,0.34,'10/1 12:00am', 'Manufacturing'],
            ['American Express Company',52.55,0.01,0.02,'9/1 10:00am', 'Finance'],
            ['American International Group, Inc.',64.13,0.31,0.49,'9/1 11:00am', 'Services'],
            ['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am', 'Services'],
            ['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am', 'Manufacturing'],
            ['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am', 'Services'],
            ['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am', 'Finance'],
            ['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am', 'Manufacturing'],
            ['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am', 'Manufacturing'],
            ['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am', 'Manufacturing'],
            ['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am', 'Automotive'],
            ['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am', 'Computer'],
            ['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am', 'Manufacturing'],
            ['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am', 'Computer'],
            ['International Business Machines',81.41,0.44,0.54,'9/1 12:00am', 'Computer'],
            ['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am', 'Medical'],
            ['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am', 'Finance'],
            ['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am', 'Food'],
            ['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am', 'Medical'],
            ['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am', 'Computer'],
            ['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am', 'Services', 'Medical'],
            ['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am', 'Food'],
            ['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am', 'Retail'],
            ['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am', 'Manufacturing'],
            ['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am', 'Computer'],
            ['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am', 'Services'],
            ['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am', 'Retail'],
            ['Walt Disney Company (The) (Holding Company)',29.89,0.24,0.81,'9/1 12:00am', 'Services']
            ]
          }
        )
        ,columns:[
          {id:'company',header: "Company", width: 80, sortable: true, dataIndex: 'company'}
          ,{header: "Price",               width: 40, sortable: true, renderer: Ext.util.Format.usMoney, dataIndex: 'price'}
          ,{header: "Change",              width: 40, sortable: true, dataIndex: 'change'}
          ,{header: "% Change",            width: 40, sortable: true, dataIndex: 'pctChange'}
          ,{header: "Last Updated",        width: 40, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
        ]
        ,viewConfig:{forceFit:true}
      }; // eo config object
     
      // apply config
      Ext.apply(this, Ext.apply(this.initialConfig, config));
       
      // call parent
      ExampleGrid.superclass.initComponent.apply(this, arguments);
    } // eo function initComponent
     
    });
     
    //~ Ext.reg('examplegrid', ExampleGrid);
    
    
    
    Ext.onReady(function() {
      var leftPanel = {
          layout: 'form',
          flex:1,
          autoScroll:true,
          items: [
            {xtype: 'textfield', fieldLabel: 'A', value:'A'},
            {xtype: 'textfield', fieldLabel: 'B', value:'B'},
            {xtype: 'textfield', fieldLabel: 'C', value:'C'},
            {xtype: 'textfield', fieldLabel: 'D', value:'D'},
            {xtype: 'textfield', fieldLabel: 'E', value:'E'},
            {xtype: 'textfield', fieldLabel: 'F', value:'F'},
            {xtype: 'textfield', fieldLabel: 'G', value:'G'}
          ]
      };
      
      var grid1 = new ExampleGrid({title:"First Grid",collapsible:true});
      var gridbox1 = {flex:1,autoScroll:true,items:grid1,xtype:'container',layout:'fit'}
      var grid2 = new ExampleGrid({title:"Second Grid",collapsible:true});
      var gridbox2 = {flex:1,autoScroll:true,items:grid2,xtype:'container',layout:'fit'}
      var grid3 = new ExampleGrid({title:"Third Grid",collapsible:true});
      var gridbox3 = {flex:1,autoScroll:true,items:grid3,xtype:'container',layout:'fit'}
      
      var rightPanel = {
          //~ layout: 'form',
          layout:   'vbox', layoutConfig: {align:'stretch'},
          flex:1,
          autoScroll:true,
          items: [ gridbox1, gridbox2, gridbox3 ]
      };
      
      var win = new Ext.Window({
        width: 600, height:400,
        layout:'fit',
        maximizable: true,
        items: {
          layout: 'hbox', layoutConfig: {align:'stretch'},
          items: [leftPanel,rightPanel]
        }
      });
      win.show();
    });
    </script>
    </head><body>
    </body></html>
    I tried things like
    grid1.on('collapse',function(){ rightPanel.doLayout()});
    or
    grid1.on('collapse',function(){ rightPanel.onResize()});
    but without success.

    Thanks in advance for any hint!

    Luc

  2. #2
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,507
    Vote Rating
    56
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    vbox in 3.* doesn't handle collapsed panels well. It's a known issue. I suspect the 4.0 code will clean this up.

    Meanwhile, I took a look at it: http://www.sencha.com/forum/showthre...266#post463266

  3. #3
    Sencha User lsaffre's Avatar
    Join Date
    Aug 2009
    Location
    Estonia
    Posts
    34
    Vote Rating
    0
    lsaffre is on a distinguished road

      0  

    Default


    Thank you, Animal! Yes, my problem is a duplicate of nolo866's post.
    I applied your patch to my showcase, but unfortunately didn't manage to make it work (using Ext 3.2.1).
    Here is what I did:
    Code:
    <html><head>
    <!--  -->
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title id="title">2010-09-12</title>
    <!-- ** CSS ** -->
    <!-- base library -->
    <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
    <!-- overrides to base library -->
    <!-- ** Javascript ** -->
    <!-- ExtJS library: base/adapter -->
    <script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
    <!-- ExtJS library: all widgets -->
    <script type="text/javascript" src="../../ext-all-debug.js"></script>
    <script type="text/javascript">
    
    
    Ext.override(Ext.layout.BoxLayout, {
        getVisibleItems: function(ct) {
            var ct  = ct || this.container,
                t   = ct.getLayoutTarget(),
                cti = ct.items.items,
                len = cti.length,
                i, c, items = [];
    
            for (i = 0; i < len; i++) {
                if((c = cti[i]).rendered && this.isValidParent(c, t) && c.hidden !== true){ // no collapsed check
                    items.push(c);
                }
            }
    
            return items;
        }
    });
    
    Ext.override(Ext.layout.VBoxLayout, {
        calculateChildBoxes: function(visibleItems, targetSize) {
            var visibleCount = visibleItems.length,
    
                padding      = this.padding,
                topOffset    = padding.top,
                leftOffset   = padding.left,
                paddingVert  = topOffset  + padding.bottom,
                paddingHoriz = leftOffset + padding.right,
    
                width        = targetSize.width - this.scrollOffset,
                height       = targetSize.height,
                availWidth   = Math.max(0, width - paddingHoriz),
    
                isStart      = this.pack == 'start',
                isCenter     = this.pack == 'center',
                isEnd        = this.pack == 'end',
    
                nonFlexHeight= 0,
                maxWidth     = 0,
                totalFlex    = 0,
    
                //used to cache the calculated size and position values for each child item
                boxes        = [],
    
                //used in the for loops below, just declared here for brevity
                child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedHeight, horizMargins, stretchWidth;
    
                //gather the total flex of all flexed items and the width taken up by fixed width items
                for (i = 0; i < visibleCount; i++) {
                    child = visibleItems[i];
                    childHeight = child.collapsed ? child.getHeight() : child.height;
                    childWidth  = child.width;
                    canLayout   = !child.hasLayout && Ext.isFunction(child.doLayout);
    
    
                    // Static height (numeric) requires no calcs
                    if (!Ext.isNumber(childHeight)) {
    
                        // flex and not 'auto' height
                        if (child.flex && !childHeight) {
                            totalFlex += child.flex;
    
                        // Not flexed or 'auto' height or undefined height
                        } else {
                            //Render and layout sub-containers without a flex or width defined, as otherwise we
                            //don't know how wide the sub-container should be and cannot calculate flexed widths
                            if (!childHeight && canLayout) {
                                child.doLayout();
                            }
    
                            childSize = child.getSize();
                            childWidth = childSize.width;
                            childHeight = childSize.height;
                        }
                    }
    
                    childMargins = child.margins;
    
                    nonFlexHeight += (childHeight || 0) + childMargins.top + childMargins.bottom;
    
                    // Max width for align - force layout of non-layed out subcontainers without a numeric width
                    if (!Ext.isNumber(childWidth)) {
                        if (canLayout) {
                            child.doLayout();
                        }
                        childWidth = child.getWidth();
                    }
    
                    maxWidth = Math.max(maxWidth, childWidth + childMargins.left + childMargins.right);
    
                    //cache the size of each child component
                    boxes.push({
                        component: child,
                        height   : childHeight || undefined,
                        width    : childWidth || undefined
                    });
                }
    
                //the height available to the flexed items
                var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert));
    
                if (isCenter) {
                    topOffset += availableHeight / 2;
                } else if (isEnd) {
                    topOffset += availableHeight;
                }
    
                //temporary variables used in the flex height calculations below
                var remainingHeight = availableHeight,
                    remainingFlex   = totalFlex;
    
                //calculate the height of each flexed item, and the left + top positions of every item
                for (i = 0; i < visibleCount; i++) {
                    child = visibleItems[i];
                    calcs = boxes[i];
    
                    childMargins = child.margins;
                    horizMargins = childMargins.left + childMargins.right;
    
                    topOffset   += childMargins.top;
    
                    if (isStart && child.flex && !child.collapsed && !child.height) {
                        flexedHeight     = Math.ceil((child.flex / remainingFlex) * remainingHeight);
                        remainingHeight -= flexedHeight;
                        remainingFlex   -= child.flex;
    
                        calcs.height = flexedHeight;
                        calcs.dirtySize = true;
                    }
    
                    calcs.left = leftOffset + childMargins.left;
                    calcs.top  = topOffset;
    
                    switch (this.align) {
                        case 'stretch':
                            stretchWidth = availWidth - horizMargins;
                            calcs.width  = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
                            calcs.dirtySize = true;
                            break;
                        case 'stretchmax':
                            stretchWidth = maxWidth - horizMargins;
                            calcs.width  = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
                            calcs.dirtySize = true;
                            break;
                        case 'center':
                            var diff = availWidth - calcs.width - horizMargins;
                            if (diff > 0) {
                                calcs.left = leftOffset + horizMargins + (diff / 2);
                            }
                    }
    
                    topOffset += calcs.height + childMargins.bottom;
                }
    
            return {
                boxes: boxes,
                meta : {
                    maxWidth: maxWidth
                }
            };
        }
    });
    
    
    
    
    
    
    
    
    
    // taken from http://examples.extjs.eu/
    ExampleGrid = Ext.extend(Ext.grid.GridPanel, {
      initComponent:function() {
      // hard coded - cannot be changed from outside
      var config = {
        store: new Ext.data.SimpleStore({
          id:0
          ,fields:[
            {name: 'company'}
            ,{name: 'price', type: 'float'}
            ,{name: 'change', type: 'float'}
            ,{name: 'pctChange', type: 'float'}
            ,{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
            ,{name: 'industry'}
            ,{name: 'desc'}
          ]
          ,data:[
            ['3m Co',71.72,0.02,0.03,'8/1 12:00am', 'Manufacturing'],
            ['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am', 'Manufacturing'],
            ['Altria Group Inc',83.81,0.28,0.34,'10/1 12:00am', 'Manufacturing'],
            ['American Express Company',52.55,0.01,0.02,'9/1 10:00am', 'Finance'],
            ['American International Group, Inc.',64.13,0.31,0.49,'9/1 11:00am', 'Services'],
            ['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am', 'Services'],
            ['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am', 'Manufacturing'],
            ['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am', 'Services'],
            ['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am', 'Finance'],
            ['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am', 'Manufacturing'],
            ['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am', 'Manufacturing'],
            ['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am', 'Manufacturing'],
            ['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am', 'Automotive'],
            ['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am', 'Computer'],
            ['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am', 'Manufacturing'],
            ['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am', 'Computer'],
            ['International Business Machines',81.41,0.44,0.54,'9/1 12:00am', 'Computer'],
            ['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am', 'Medical'],
            ['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am', 'Finance'],
            ['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am', 'Food'],
            ['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am', 'Medical'],
            ['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am', 'Computer'],
            ['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am', 'Services', 'Medical'],
            ['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am', 'Food'],
            ['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am', 'Retail'],
            ['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am', 'Manufacturing'],
            ['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am', 'Computer'],
            ['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am', 'Services'],
            ['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am', 'Retail'],
            ['Walt Disney Company (The) (Holding Company)',29.89,0.24,0.81,'9/1 12:00am', 'Services']
            ]
          }
        )
        ,columns:[
          {id:'company',header: "Company", width: 80, sortable: true, dataIndex: 'company'}
          ,{header: "Price",               width: 40, sortable: true, renderer: Ext.util.Format.usMoney, dataIndex: 'price'}
          ,{header: "Change",              width: 40, sortable: true, dataIndex: 'change'}
          ,{header: "% Change",            width: 40, sortable: true, dataIndex: 'pctChange'}
          ,{header: "Last Updated",        width: 40, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
        ]
        ,viewConfig:{forceFit:true}
        ,collapsible: true
        ,allowQueuedExpand: false
      }; // eo config object
     
      // apply config
      Ext.apply(this, Ext.apply(this.initialConfig, config));
       
      // call parent
      ExampleGrid.superclass.initComponent.apply(this, arguments);
    } // eo function initComponent
     
    });
     
    //~ Ext.reg('examplegrid', ExampleGrid);
    
    
    
    Ext.onReady(function() {
      var leftPanel = {
          layout: 'form',
          flex:1,
          autoScroll:true,
          items: [
            {xtype: 'textfield', fieldLabel: 'A', value:'A'},
            {xtype: 'textfield', fieldLabel: 'B', value:'B'},
            {xtype: 'textfield', fieldLabel: 'C', value:'C'},
            {xtype: 'textfield', fieldLabel: 'D', value:'D'},
            {xtype: 'textfield', fieldLabel: 'E', value:'E'},
            {xtype: 'textfield', fieldLabel: 'F', value:'F'},
            {xtype: 'textfield', fieldLabel: 'G', value:'G'}
          ]
      };
      
    
      var grid1 = new ExampleGrid({title:"First Grid",listeners: { 'expand': onExpandCollapse, 'collapse': onExpandCollapse }});
      var gridbox1 = {flex:1,autoScroll:true,items:grid1,xtype:'container',layout:'fit'}
      var grid2 = new ExampleGrid({title:"Second Grid",listeners: { 'expand': onExpandCollapse, 'collapse': onExpandCollapse }});
      var gridbox2 = {flex:1,autoScroll:true,items:grid2,xtype:'container',layout:'fit'}
      var grid3 = new ExampleGrid({title:"Third Grid",listeners: { 'expand': onExpandCollapse, 'collapse': onExpandCollapse }});
      var gridbox3 = {flex:1,autoScroll:true,items:grid3,xtype:'container',layout:'fit'}
      
      var rightPanel = new Ext.Panel({
          //~ layout: 'form',
          
          layout:   { type: 'vbox', align: 'stretch'},
          //~ layout:   'vbox', layoutConfig: {align:'stretch'},
          flex:1,
          autoScroll:true,
          items: [ gridbox1, gridbox2, gridbox3 ]
      });
      
        function onExpandCollapse(c) {
    //      Horrible Ext 2.* collapse handling has to be defeated...
            if (c.queuedBodySize) {
                delete c.queuedBodySize.width;
                delete c.queuedBodySize.height;
            }
            rightPanel.doLayout();
        }
      
      
      var win = new Ext.Window({
        width: 600, height:400,
        layout:'fit',
        maximizable: true,
        items: {
          layout: 'hbox', layoutConfig: {align:'stretch'},
          items: [leftPanel,rightPanel]
        }
      });
      win.show();
    });
    </script>
    </head><body>
    </body></html>
    What am I missing? Any hint welcome!

    Luc

Similar Threads

  1. hbox/vbox how-to?
    By logicmedia in forum Sencha Touch 1.x: Discussion
    Replies: 1
    Last Post: 8 Sep 2010, 11:03 AM
  2. Has anyone tried using hbox or vbox?
    By artalat in forum Sencha Touch 1.x: Discussion
    Replies: 0
    Last Post: 17 Jun 2010, 11:53 AM
  3. Vbox / ListView
    By Bleak in forum Ext 3.x: Help & Discussion
    Replies: 5
    Last Post: 4 May 2010, 5:22 AM
  4. vbox 50/50 height?
    By westvovik in forum Ext 3.x: Help & Discussion
    Replies: 1
    Last Post: 29 Apr 2010, 9:05 AM

Thread Participants: 1