I need some help on understanding layouts better. I watched some of the screencasts and the examples, etc. But I can't get done what I need and I think I'm not understanding things correctly.
I want to create a page with a Grid on top with a 100% width of the viewport. (Actually in my real page it's in a specific div but let's just assume...) Then below this grid, I need a TreePanel on the left for 1/3 of the width and the other 2/3 by a second Grid.
I'm trying to use the TableLayout so that I can have the first Grid span the two columns on the first row and second row would have the tree and the 2nd grid one besides the other.
I have my top grid and my tree on the page but the height of the top grid is not calculated automatically, it's just a few pixel high no matter how many rows are in there, and if I resize the browser window I don't get horizontal scrollbars on the grid.
So, my guess is that really the TableLayout is not what I should be using, but maybe I'm wrong. How can I achieve this layout ? Would I be better off using the BorderLayout ?
Here's the JS code I have (distributePMPanel is just a plain div on the page and I have another JS component that is loaded after that creates the Tree with a renderTo of 'mytree' so the Tree outputs in the second item's div):
_I.mainPanel = new Ext.Panel({
id:'main-panel',
renderTo: 'distributePMPanel',
baseCls: 'x-plain',
layout:'table',
layoutConfig: {columns:2},
items: [
new Ext.grid.GridPanel({
store: new Ext.data.JsonStore({
fields: Ext.decode(_I.options.pmStore),
root: 'pmData',
idProperty: 'id',
data: Ext.decode(_I.options.pmData)
}),
colModel: new Ext.grid.ColumnModel({
defaults: {
sortable : true
},
columns: Ext.decode(_I.options.pmColumns)
}),
colspan: 2
}),
{
id: 'mytree'
},
{
html: 'Grid 2'
}
]
});
};
Also, I have the following CSS:
#distributePMPanel table.x-table-layout { width: 100%; }
#distributePMPanel .x-panel-body { border-width: 0; }
I would definitely look at borderlayout.
Your grid is North
Your tree is West
Your other grid is Center
Should be a snap with borderlayout.
Related
I am working on making a container in extJS that will dynamically add Attribute Grids depending on the user clicking a row on another grid within my form. I would like for this container which is housing the Attribute
Grids to be scrollable so that the container would remain a fixed size, but the user can add or remove as many attribute grids inside as they'd like.
Here is a snippet of my code that I am using to create my container:
Ext.define('SSAF.plugin.CHEF.view.chefAttributeGridContainer', {
extend: 'Ext.container.Container',
autoScroll: true,
layout: {
type: 'vbox'
},
width: 400,
border: 1,
style: {borderColor:'#000000', borderStyle:'solid', borderWidth:'1px'},
defaults: {
labelWidth: 80,
// implicitly create Container by specifying xtype
xtype: 'datefield',
flex: 1,
style: {
padding: '10px'
}
},
items: [
Ext.create('SSAF.plugin.CHEF.view.chefRunListAttributesGrid'),
Ext.create('SSAF.plugin.CHEF.view.chefRunListAttributesGrid'),
Ext.create('SSAF.plugin.CHEF.view.chefRunListAttributesGrid'),
Ext.create('SSAF.plugin.CHEF.view.chefRunListAttributesGrid'),
Ext.create('SSAF.plugin.CHEF.view.chefRunListAttributesGrid')
]
});
Although I have added the autoScroll attribute to my grid, I am not receiving the intended effect.
Here is how it currently looks:
I would like it to remain a fixed size just like all of my other components within my layout:
Any idea as to what I may be missing in order to achieve my desire effect?
Thanks
I was able to solve my problem with the solution offered by this post:
Grid AutoScroll
i found 2 similar questions here, but they are not helped me, my code is:
var grid = Ext.create('Ext.grid.Panel', {
autoScroll: true,
// if set this to any numeric value, then everything works just good, but
// i was hoping that `ExtJS` already can detect browser window height, am i wrong ?
height: '100%',
title: 'Products',
store: store,
itemId: 'product_grid',
columns: [.. columns skipped ...],
plugins: [ rowEditing ],
dockedItems: [ ..addRow button here..]
});
var panel = Ext.create('Ext.panel.Panel', {
autoScroll: true,
items: [
{
xtype: 'productGrid'
}
]
});
Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: panel
});
What i need i scrollable grid filling whole browser window, but grid here does not expand
in height, so if grid has 0 rows, then it has 0 height and when i push "Add row", then
added row looks obscured by scrollbars and this looks ugly.
Also when grid contain more rows than could fit in browser window, then page scrollbar appears (not grid's scrollbar!) and this scrolls whole page so button bar scrolled away, which is also undesirable and ugly.
Any ideas what is wrong with my setup.
UPDATE:
Finally fixed it, intermediate panel should also contain layout: 'fit'
There's a couple things you can do here. First, use the fit layout on your Viewport as it will force its child component to fill the available space. Second, grids are panels. You don't need to nest a grid in a panel, and probably shouldn't.
The autoScroll config doesn't work on grids. Scrolling in both directions is enabled by default, but if you need to change it use the scroll property. Lastly, the height config only takes a number and doesn't work with strings or percentages. If you specify a height, it overrides any height given by the layout manager and you don't need it for fit layouts.
var grid = Ext.create('Ext.grid.Panel', {
title: 'Products',
store: store,
itemId: 'product_grid',
columns: [/* ... */],
plugins: [rowEditing],
dockedItems: [/* ... */]
});
var viewport = Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [grid]
});
Adding a viewConfig to the grid, strangely enough, solved my problem of gridpanel having no explicit height in floating window with vbox layout, containing just a form and a grid.
xtype: 'gridpanel',
store: 'DCLocations',
columnLines: true,
autoScroll : true,
viewConfig : {
emptyText : i18n.message.noresultstodisplay,
},
Scenario description: I have a border layout with an ExtJS container containing one-to-many windows an a panel (acting as a Taskbar). I want the taskbar to be always on top. If a Window is active and consequently in front, calling toFront does not put it in front as expected.
The ExtJS Windows which remain in front is within the center area of the Border layout, whereas the panel acting as taskbar is within the south area, as follows:
items: [
{
xtype: 'maincontainer', id:'maincontainer',
region : 'center'
},
{
xtype: 'launchpanel', id:'launchpanel',
region: 'south',
collapsible : true,
}
],
where maincontainer and launchpanel extend Ext.container.Container and Ext.panel.Panel respectively. This code is within the main container which is the only item in the ExtJS MVC application's Viewport.
How do I get the launchpanel to be always in front / on top?
From what I've read in the meantime what appears in front is determined by the CSS z-index property.
Then I found this answer about how to set the z-index for a panel. Hence I set the z-index for the Panel each time it is rendered by having the following snippet in the controller:
'launchpanel': {
expand: function(panel) {
panel.getEl().setStyle('z-index','80000');
},
...
Still, if anyone has a better way of doing the above, please share!
Using Extjs, I've got a TabPanel containing two Panels. Those panels do not automatically expand vertically. All layout are set with type 'fit' and forceFit is true.
Edit:
I've updated my code according the Kunal's suggestion.
To describe the interface: you have a tree list containing several nodes. When the user clicks on one of those nodes it opens a tab (calling the function ZombieTab(zombie_ip)) with two sub-tabs (ZombieTab_MainTab and ZombieTab_Commands).
Editing the code with Kunal's suggestion had the following effect: We can see that the ZombieTab_Commands's bottom bars appears at the top of the panel and as a result, all components of the tab are not displayed.
Is the main tab of your, which is ZombieTab, is taking the whole space?
If yes, I would make changes for child panels as
ZombieTab_MainTab.superclass.constructor.call(this, {
id: 'zombie-main-tab',
layout:'fit',
title: 'Main',
items: {
layout:'border',
items:[top_bar, logs]
}
});
similarly for other child panel as well.
For the Toolbar in Command Tab, try replacing with normal Ext Toolbar and see the effect.
bbar: new Ext.Toolbar({
id: 'exploits-bbar-zombie-'+zombie_ip,
text: 'ready',
border: false,
iconCls: 'x-status-valid',
items : [ { text: 'test'} ]
})
I want to include an ExtJS GridPanel inside a larger layout, which in turn must be rendered inside a particular div in some pre-existing HTML that I don't control.
From my experiments, it appears that the GridPanel only resizes itself correctly if it's within a Viewport. For instance, with this code the GridPanel automatically resizes:
new Ext.Viewport(
{
layout: 'anchor',
items: [
{
xtype: 'panel',
title: 'foo',
layout: 'fit', items: [
{
xtype: 'grid',
// define the grid here...
but if I replace the first three lines with the lines below, it doesn't:
new Ext.Panel(
{
layout: 'anchor',
renderTo: 'RenderUntoThisDiv',
The trouble is, Viewport always renders directly to the body of the HTML document, and I need to render within a particular div.
If there is a way to get the GridPanel to resize itself correctly, despite not being contained in a ViewPort, that would be ideal. If not, if I could get the Viewport to render the elements within the div, I'd be fine with that. All of my ExtJS objects can be contained within the same div.
Does anybody know of a way to get a GridPanel to resize itself correctly, but still be contained inside some non-ExtJS-generated HTML?
To resize Ext JS components when they are not in a Viewport, you need to pass along browser window resize events.
Ext.EventManager.onWindowResize(panel.doLayout, panel);
In your example, store the Panel into var panel, and then set up the event handler after the var declaration but still inside of Ext.onReady.
Here is a full single page solution:
<html>
<head>
<link rel="stylesheet" href="ext-3.1.1/resources/css/ext-all.css" />
<script src="ext-3.1.1/adapter/ext/ext-base.js"></script>
<script src="ext-3.1.1/ext-all-debug.js"></script>
<script>
Ext.BLANK_IMAGE_URL = 'ext-3.1.1/resources/images/default/s.gif';
Ext.onReady(function(){
var panel = new Ext.Panel({
renderTo: 'areaDiv',
layout: 'fit',
items: [{
height: 200,
title: 'foo',
xtype: 'grid',
cm: new Ext.grid.ColumnModel([
{header: "id", width: 400},
{header: "name", width: 400}
]),
store: new Ext.data.ArrayStore({
fields: ['id','name'],
data: [[1,'Alice'],[2,'Bill'],[3,'Carly']]
})
}]
});
//pass along browser window resize events to the panel
Ext.EventManager.onWindowResize(panel.doLayout, panel);
});
</script>
</head>
<body>
header
<div id="areaDiv" style="padding:30px;"></div>
footer
</body>
</html>
Note that I've removed the redundant panel (a GridPanel is a Panel, so no need to wrap it), and used layout fit instead of anchor. Layout fit is actually the key to a fluid layout. Make the browser smaller, then bigger. You'll see the grid always fills the entire width, with the exception of the padding.
I don't have enough reputation to "comment anywhere" yet, but I do have a fix to the "not working when window is resized smaller" problem described by HOCA. I was having the same problem too, using the solution outlined by this answer. After Googling around for a while, I found this thread on the sencha.com website. Using a similar technique to the one described there seems to work better cross-browser (using the exact solution offered there seems to work somewhat differently between FF/IE).
Ext.EventManager.onWindowResize(function() {
// pass "true" to get the contendWidth (excluding border/padding/etc.)
mainPanel.setWidth(Ext.getBody().getWidth(true));
// seems to be no need to call mainPanel.doLayout() here in my situation
});
In IE6 and Chrome your solution doesn't seem to work when the browser window is resized/made smaller that the original size. It does, however, resize properly when the browser window is resized larger. Does the Ext.EventManager.onWindowResize(panel.doLayout, panel) not fire when the browser window is made smaller?
I solved it by setting the layout: 'fit' to the panel that contains the grid
var myGridTab = new Ext.Panel({
layout: 'border',
region: 'center',
autoScroll: true,
animCollapse: false,
forceFit: true,
title: ' My Grid Tab ',
split: true,
border: false,
items: [
{
region: 'center',
**layout: 'fit',**
autoScroll: true,
items: [myGrid],
height: 150,
forceFit: true
}]
});