PDA

View Full Version : TabPanel child of layout: "vbox" does not render



dereks
7 Sep 2010, 12:58 PM
Is it possible to put a vbox inside of a TabPanel tab?

I have tried many combinations of nesting Panels, setting fixed width/height, etc. but I just can't get a vbox (or an hbox) to render inside a tab of a TabPanel.

It seems like this is purely a layout issue, and that the tab is rendering with zero height... but I don't know that for sure.

Here is my test case:


MyTabPanel = Ext.extend( Ext.TabPanel, {
title: 'MyTabPanel',
width: '600',
height: '600',
activeTab: 0,
renderTo: Ext.getBody(),

initComponent: function() {

var config = {

items: [ {
xtype: 'panel',
title: 'TAB1, a vbox layout with children',
layout:'vbox',
layoutConfig: {
align : 'stretch',
pack : 'start',
},

items: [{
title: "vbox child1",
flex: 1,
html: "Why does this not show up?",
}, {
title: "vbox child2",
flex: 2,
html: "Why does this not show up?",
}]
}],
}
Ext.apply(this, Ext.apply(this.initialConfig, config));
MyTabPanel.superclass.initComponent.apply(this, arguments);
}
} );

mytabpanel = new MyTabPanel();


Any assistance is greatly appreciated. Thanks!

Condor
8 Sep 2010, 12:20 AM
Try adding:

layoutOnTabChange:true

dereks
8 Sep 2010, 9:54 AM
Condor: Thank you for your reply and the "layoutOnTabChange" suggestion.

Unfortunately, there was no change. I even added a second tab, so I could trigger the "onTabChange" event.

Is this a bug?

Here is the diff I applied:


--- test1.1.js 2010-09-08 10:53:18.825014503 -0700
+++ test1.js 2010-09-08 10:51:00.637011970 -0700
@@ -5,6 +5,7 @@
height: '600',
activeTab: 0,
renderTo: Ext.getBody(),
+ layoutOnTabChange:true, // no change when I added this line...

initComponent: function() {

@@ -28,6 +29,9 @@
flex: 2,
html: "Why does this not show up?",
}]
+ }, {
+ title: 'TAB2',
+ html: "I added this 2nd tab to test the OnTabChange event.",
} ],
}
Ext.apply(this, Ext.apply(this.initialConfig, config));

darthwes
8 Sep 2010, 10:45 AM
Let's try adding



deferredRender: false


on the tab panel. I imagine that will work. Alternatively,
forceLayout: true on the panels inside the tab panel might be the special sauce you'd prefer. Try those out and let us know if they help. Good luck!

dereks
8 Sep 2010, 12:04 PM
Thank you for the continued suggestions.

I tried both "deferredRender: false" and "forceLayout: true", but the results were the same. I even tried both of them at the same time: no change.

(Here are the diffs, just to prove that I put the options in the right place.)


--- test1.2.js 2010-09-08 12:56:50.742014133 -0700
+++ test1.js 2010-09-08 12:57:29.230015118 -0700
@@ -5,7 +5,8 @@
height: '600',
activeTab: 0,
renderTo: Ext.getBody(),
- layoutOnTabChange:true, // no change when I added this line...
+// layoutOnTabChange:true, // no change when I added this line...
+ deferredRender: false,

initComponent: function() {
--- test1.3.js 2010-09-08 12:58:54.442013778 -0700
+++ test1.js 2010-09-08 12:59:30.270013935 -0700
@@ -6,7 +6,7 @@
activeTab: 0,
renderTo: Ext.getBody(),
// layoutOnTabChange:true, // no change when I added this line...
- deferredRender: false,
+// deferredRender: false,

initComponent: function() {

@@ -15,6 +15,7 @@
items: [ {
xtype: 'panel',
title: 'TAB1, a vbox layout with children',
+ forceLayout: true,
layout:'vbox',
layoutConfig: {
align : 'stretch',
@@ -32,6 +33,7 @@
}]
}, {
title: 'TAB2',
+ forceLayout: true,
html: "I added this 2nd tab to test the OnTabChange event.",
} ],
}
--- test1.4.js 2010-09-08 13:00:34.425015112 -0700
+++ test1.js 2010-09-08 13:00:40.770014288 -0700
@@ -6,7 +6,7 @@
activeTab: 0,
renderTo: Ext.getBody(),
// layoutOnTabChange:true, // no change when I added this line...
-// deferredRender: false,
+ deferredRender: false,

initComponent: function() {

darthwes
9 Sep 2010, 1:08 PM
Because you're trying to make a tabpanel render to the body. Here's some suggestions. I'd change the override to a window and give it the tabpanel as it's items config. Alternatively, and much better, would be to remove renderTo, create a window and make it's items config the tabpanel. You can then use .show(Ext.getBody()) from your window.

dereks
9 Sep 2010, 1:54 PM
Progress! As per darthwes' suggestion, I changed the last bit of my test case to look like this:


//mytabpanel = new MyTabPanel(); // BROKE
Ext.reg( 'mytabpanel', MyTabPanel );

Ext.onReady( function() {

var win = new Ext.Window({
layout:'fit',
height: 300,
items: [{ xtype: 'mytabpanel' }]
});
win.show(Ext.getBody());

} );


And now I can see the child vbox entries, correctly balanced as per the "flex" settings. w00t!

But I don't understand why rendering to the Ext.Window is necessary, or why it fixes the problem. What does the Window do that makes the vbox work? Is the TabPanel parent missing something?

In my application code (as opposed to the simple test case above), my vbox is embedded within a TabPanel within a BorderLayout within a TabPanel within a Viewport -- and I see the exact same problem there. What do I need to do to fix my app? Put my fullscreen Viewport within a Panel? Or a Window? Me confused...

dereks
10 Sep 2010, 6:03 PM
After playing around with my app and trying various things, I've learned that the problem is with the "height" variable. If I set the height to a fixed pixel height, then the vbox works as expected.

But I don't want a fixed pixel height; I want the vbox to fill up all available space, partitioning it out as per the "flex" settings of its children. I have still not found a way to do that (for any 'item' of a TabPanel). Using a parent Container of layout: 'fit' is not working.

I've tried using autoHeight: true, and wrapping the vbox in a Panel of layout: "anchor", and then setting anchor: "100%, 100%" on my vbox... and then on a Panel wrapper around my vbox. I also tried wrapping the vbox with a Panel of layout: "fit". The width is always working as expected (taking up 100% of the available space), but the height of the vbox always collapses to zero (and thus invisible)... *unless* I set a fixed pixel height like height: 500.

Setting the fixed pixel height on any of the parent Containers works, as long as it's contained by the TabPanel... at one point I had nested panels three levels deep, because I was playing around with different layout options. If I set a fixed pixel height on any of the parent wrapper Panels, then the vbox works.

And, when I used the Window in the lsat test above, the Window also collapses itself to zero height -- exactly like I see in the TabPanel -- unless I manually give it the fixed height option.

From my perspective, it looks like the TabPanel reduces itself to zero height unless a parent Container has a fixed-pixel height. Parent Containers of layout: 'fit' or 'anchor' do not set a fixed pixel height, and thus, the TabPanel item collapses itself to zero height. I consider that a bug, because it does not allow for dynamic pixel heights on TabPanel children.

In summary: Is there a way to make the vbox work, but not set a fixed height? Can you make my code above work without that hard-coded "height: 300" in it?

dereks
10 Sep 2010, 6:29 PM
Solved!

The TabPanel I was having a problem with was in region: "east" of a BorderLayout. I had to set the layout of that parent region to be layout: 'fit'... even though the TabPanel itself wasn't having a layout problem. Only its children (items) were.

In all my monkeying around, I was trying to change layouts of Panels contained within the TabPanel. But all those failed because there was no height available. The Container of the TabPanel -- in this case, my BorderLayout's region: "east" -- had to be set to layout: 'fit'.

Hope this helps someone else save the time...

Animal
10 Sep 2010, 11:27 PM
Not it won't. All new users will continue to totally ignore all documentation, all books, all examples, all advice here, and IGNORE layouts.

netpuppy
7 Mar 2011, 4:22 PM
thanks for that descriptive explanation dereks, you saved me heaps of mucking around.

I set my fit layout on the tabpage that contained my vbox which also worked the same.


region: 'east',collapsible: false,collapsed: false,margins: '0, 5, 0, 0', split: true,width: 620,xtype: 'tabpanel',activeTab: 0
,items: [{title: '[+membership.member.details+]',autoScroll:true,items:[details]}
,{title: '[+membership.member.profiles+]',autoScroll:true,layout: 'fit',items:[profiles]} ]}