PDA

View Full Version : How can I make ExtJS 4.2.1 empty grid respect flex layout value?



xjscrafter
12 Jun 2014, 9:01 AM
In the code below, if you replace:


Ext.create('Ext.container.Container'

with:


Ext.create('Ext.container.Viewport'

The grid correctly occupy 70% / 30% of the available area.

But when the code has Container and not Viewport, the grids are very small.

Of course my real code is within a larger application, so I cannot use a Viewport at that point, I must use container.


Ext.define('MyGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.myGrid',
columns: [{
text: 'First Name',
dataIndex: 'fname'
}],
store: Ext.create('Ext.data.Store', {
fields: ['fname']
})
});


Ext.onReady(function() {
Ext.create('Ext.container.Container', {
renderTo: Ext.getBody(),
layout: 'fit',
items: [{
xtype: 'container',
layout: {
type: 'vbox',
align: 'stretch'
},
defaults: {
autoScroll: true,
bodyPadding: 0
},
items: [{
xtype: 'myGrid',
itemId: 'grid1',
flex: 7
}, {
xtype: 'splitter'
},{
xtype: 'tabpanel',
itemId: 'mypanel',
width: 400,
height: 400,
renderTo: document.body,
flex: 3,
scroll: true,
resizable: false,
activeTab: 0,
items: [{
xtype: 'myGrid',
itemId: 'tabgrid1',
title: 'My Grid Tab One'
},{
xtype: 'myGrid',
itemId: 'tabgrid2',
title: 'My Grid Tab Two'
}],
tabBar:{
//plain:true,
items:[{
xtype: 'tbfill'
},{
text:'????',
xtype:'image',
src: 'panelCollapseBtn.png',
closable: false,
listeners:{
'afterrender':function (comp) {
comp.getEl().on('click', function (el) {
// alert(comp.up('#mypanel').getCollapsed());
var panel = comp.up('#mypanel');
var isCollapsed = panel.getCollapsed();
//alert('is collapsed: ' + isCollapsed);
panel.header = !isCollapsed;
//panel.collapsible =isCollapsed;
comp.setSrc(isCollapsed?"panelCollapseBtn.png":"panelExpandBtn.png");
panel.toggleCollapse();


}, this);
comp.getEl().on('mouseover', function (el) {
el.target.style.cursor = "pointer";
}, this);
}
}
}]
}
}]
}]
});
});

xjscrafter
12 Jun 2014, 3:42 PM
Can anyone provide some insight?

evant
12 Jun 2014, 3:53 PM
Your outer container has no size. You're saying it's first child should fit the size to the parent, but you're not giving any size to the parent.

xjscrafter
13 Jun 2014, 10:48 AM
We're building a dynamically sized app, because the user might resize the browser window, and some might be on laptops with various smaller screen resolutions.

So do I have to set an explicit size for the parent? Can I do something where I access document.body.clientHeight or is there a better solution?

evant
14 Jun 2014, 5:42 AM
There's nothing saying the height or width of the parent needs to be static, but the outermost width/height needs to be set.

xjscrafter
14 Jun 2014, 9:16 AM
But that makes it difficult to have a UI that looks good on various screen resolutions (desktops and laptops).

xjscrafter
16 Jun 2014, 11:53 AM
I have this working when the app initially renders, but on browser window resize the lower hierarchy of sub-containers do not resize.

xjscrafter
16 Jun 2014, 2:03 PM
Should I do something on a container resize event, or perhaps afterLayout?

xjscrafter
16 Jun 2014, 3:46 PM
Any hints on this? resize and afterlayout don't seem to work. Basically after the UI is rendered, even though I am setting the width and height using document.body.clientWidth and document.body.clientHeight, on resize containers lower in hierarchy are not updating.

evant
16 Jun 2014, 3:53 PM
They aren't dynamic properties, clientWidth and clientHeight get evaluated to numbers. You need to listen to the window resize event and set the size appropriately.

xjscrafter
16 Jun 2014, 6:14 PM
When you say listen to the window resize event, you mean implement a handler for the ExtJS resize event for my container, or do you mean the window resize event outside my ExtJS code?

In that case, how do I communicate that back into my ExtJS code?

evant
16 Jun 2014, 6:21 PM
See: http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.EventManager-method-onWindowResize

xjscrafter
17 Jun 2014, 8:05 AM
SOLUTION:

To better show the problem our actual code was facing, the following code works.

The keys for me to get this to work were to give border layout an 'align' config of stretch, and to ensure that containers had 'flex' config of 1 where necessary.



Ext.define('MyGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.myGrid',
columns: [{text: 'First Name'}],
store: Ext.create('Ext.data.Store', {fields: ['fname']})
});

Ext.define('MyView', {
extend: 'Ext.container.Container',
alias: 'widget.myView',
layout: {
type: 'vbox',
align: 'stretch'
},
items: [{
xtype: 'myGrid',
title: 'My First Grid',
flex: 7,
bodyStyle: {
backgroundColor: '#ff0000'
}
}, {
xtype: 'myGrid',
title: 'My Second Grid',
flex: 3,
bodyStyle: {
backgroundColor: '#0000ff'
}
}]
});


Ext.onReady(function() {
Ext.create('Ext.container.Viewport', {
renderTo: Ext.getBody(),
layout: 'fit',
items: [{
layout: {
type: 'border',
align: 'stretch'
},
items: [{
xtype: 'container',
region: 'center',
itemId: 'gridsContainer',
layout: {
type: 'vbox',
align: 'stretch'
},
items: [{
xtype: 'myView',
flex: 1
}]
}]
}]
});
});

evant
17 Jun 2014, 10:03 PM
Your solution doesn't really match up to what you asked. In the original question you said you didn't want to use a viewport. Secondly, there is no 'stretch' configuration on a border layout. In fact, there's a whole lot of extra complication there, you can easily simplify the above code to:



Ext.onReady(function() {
Ext.create('Ext.container.Viewport', {
renderTo: Ext.getBody(),
layout: 'fit',
items: {
xtype: 'myView',
}
});
});

xjscrafter
18 Jun 2014, 8:46 AM
I mentioned viewport because I did not understand the difference I originally mentioned.

My sample code is just that, its sample code.

There may not be a stretch config for border layout, but having it seems to contribute to the result I want.

Thanks for stimulating ideas.