PDA

View Full Version : Grid in Nested layout



vinod
31 Jul 2007, 8:33 PM
Thanks to Ext Team. I am trying introduce grid in nested layout.i am having a issue while trying to collapse right (east div) side bar grid is not expanding to whole page (i.e Grid is taking fixed width),but when i collapsed on left side bar (west dive) working fine. Please guide me in rite direction . i am new to JS .


I am also including Screen Shots of the Grid behaviour


Below is my JS Code for Nested Layout
Example = function(){
return {
init : function(){
var layout = new Ext.BorderLayout(document.body, {
west: {
split:true,
initialSize: 200,
titlebar: true,
collapsible: true,
minSize: 100,
maxSize: 400
},
east: {
split:true,
initialSize: 200,
titlebar: true,
collapsible: true,
minSize: 100,
maxSize: 400
},
north: {
split:true,
initialSize: 100,
collapsible: true,
minSize: 100,
maxSize: 400
},

south: {
split:true,
initialSize: 80,
minSize: 60,
maxSize: 80,
autoScroll:true,
collapsible:true,
titlebar: true
},
center: {
autoScroll:true
}
});
layout.beginUpdate();

layout.add('west', new Ext.ContentPanel('nav', {title: 'Sidebar1', fitToFrame:true, closable:false}));
layout.add('east', new Ext.ContentPanel('Sidebar2', {title: 'Sidebar2', fitToFrame:true, closable:false}));
layout.add('north', new Ext.ContentPanel('Header', {title: 'Header',fitToFrame:true, closable:false}));
layout.add('south', new Ext.ContentPanel('Footer', {title: 'Footer',fitToFrame:true, closable:false}));
layout.add('center', new Ext.ContentPanel('Center', {title: 'Center',fitToFrame:true, closable:false}));


layout.endUpdate();
}
};

}();
Ext.EventManager.onDocumentReady(Example.init, Example, true);



Below is my HTML Code

<html>
<head>
<title>Complex Layout</title>
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />

<!-- GC --> <!-- LIBS --> <script type="text/javascript" src="../../adapter/yui/yui-utilities.js"></script> <script type="text/javascript" src="../../adapter/yui/ext-yui-adapter.js"></script> <!-- ENDLIBS -->
<script type="text/javascript" src="../../ext-all.js"></script>
<script type="text/javascript" src="../../Layout.js"></script>


</head>
<body class="ytheme-gray">
<script type="text/javascript" src="examples.js"></script><!-- EXAMPLES -->
<div id ="container">

<!----- Header Start----->
<div id="Header" class="x-layout-inactive-content">
<h2> Header <h2>

</div>

<!----- Header End----->

<!--- Side Bar 1 Start--->


<div id="nav" class="x-layout-inactive-content">
Side Bar1 Goes Here;

</div>

<!--- Side Bar 1 --- END--->

<!---- Grid Start---->
<div id="Center" class="x-layout-inactive-content">
<script type="text/javascript" src="../examples.js"></script><!-- EXAMPLES -->
<h1>Array Grid Example</h1>
<p>This example shows how to create a grid from Array data. For more details on this example, see the blog post.</p>
<p>Note that the js is not minified so it is readable. See array-grid.js</a>.</p>


<select name="location" id="location" style="display: none;">
<option value="London">London</option>
<option value="NewYork">NewYork</option>
<option value="Sydney">Sydney</option>

<option value="Belfast">Belfast</option>

<option value="Paris">Paris</option>
</select>
<!-- a place holder for the grid. requires the unique id to be passed in the javascript function, and width and height ! -->
<div id="grid-panel" >
<div id="grid"></div>
</div>
<script type="text/javascript">
/*
* Ext JS Library 1.0.1
* Copyright(c) 2006-2007, Ext JS, LLC.
* licensing@extjs.com
*
* http://www.extjs.com/license
*/

var Example = {
init : function(){
var myData = [
['john',,'male',29,'USA'],
['mary',,'female',31,'UK'],
['peter',,'male',31,'CAN'],
['jenny',,'male',31,'CAN']

];

Ext.onReady(function(){

function formatBoolean(value){
return value ? 'Yes' : 'No';
};

function formatDate(value){
return value ? value.dateFormat('M d, Y') : '';
};

var fm = Ext.form, Ed = Ext.grid.GridEditor;


var name = Ext.data.Record.create([


{name: 'name'},
{name: 'location'},
{name: 'gender'},
{name: 'age'},
{name: 'country'}
]);




var ds = new Ext.data.Store({
proxy: new Ext.data.MemoryProxy(myData),
reader: new Ext.data.ArrayReader({}, [
{name: 'name'},
{name: 'location'},
{name: 'gender'},
{name: 'age'},
{name: 'country'}
])
});

var fm = Ext.form, Ed = Ext.grid.GridEditor;


var colModel = new Ext.grid.ColumnModel([
{header: "name", width: 160, sortable: true,dataIndex: 'name',editor: new Ed(new fm.TextField({
allowBlank: false
}))},
{header: "location", width: 75, sortable: true,dataIndex: 'location',editor: new Ed(new Ext.form.ComboBox({
typeAhead: true,
triggerAction: 'all',
transform:'location',
lazyRender:true
}))
},
{id:'change',header: "gender", width: 75, sortable: true,dataIndex: 'gender',editor: new Ed(new fm.TextField({
allowBlank: false
}))},
{header: "age", width: 75, sortable: true, dataIndex: 'age',renderer: formatBoolean,
editor: new Ed(new fm.Checkbox())},

{header: "country", width: 85, sortable: true, dataIndex: 'country',editor: new Ed(new fm.TextField({
allowBlank: false
}))}

]);


// create the Grid
var grid = new Ext.grid.EditorGrid('grid', {
ds: ds,
cm: colModel,
//autoExpandColumn: 'change'
enableColLock:false
});

var layout = Ext.BorderLayout.create({
center: {
margins:{left:3,top:3,right:3,bottom:3},
panels: [new Ext.GridPanel(grid)]
}
}, 'grid-panel');

var rz = new Ext.Resizable('grid', {
wrap:true,
minHeight:100,
pinned:true,
handles: 's'
});
rz.on('resize', grid.autoSize, grid);

// render it
grid.render();






ds.load();

});

}};

Ext.onReady(Example.init, Example);
</script>

</div>
<!------ Grid End----->



<!----- Work flow side Bar Start --->
<div id="Sidebar2" class="x-layout-inactive-content">

side Bar2 Goes here

</div>
<!----- Work flow side Bar END --->






<!----- Footer start--->
<div id="Footer" class="x-layout-inactive-content">
Footer

</div>
<!----- Footer End--->
</div>
</body>
</html>

dot99
2 Aug 2007, 7:42 AM
The same problem, nothing helps.

acharis
2 Aug 2007, 9:21 AM
I took me quite a while, stepping through the code/events... but I think this is a possible workaround. Its working for me having a BorderLayout page with a Center region that has a grid.



<div id="canvas">
<div id="header" class="x-layout-inactive-content">Header Content</div>
<div id="nav" class="x-layout-inactive-content">Navigation Content</div>
<div id="content" class="x-layout-inactive-content"><div id="results-grid"></div></div>
<div id="footer" class="x-layout-inactive-content">Footer Content</div>
</div>




var layout = new Ext.BorderLayout(document.body, {
north: {
split:false,
initialSize: 35
},
south: {
split:false,
initialSize: 20
},
west: {
split:true,
initialSize: 200,
titlebar: true,
collapsible: true,
minSize: 100,
maxSize: 400
},
center: {
fitToFrame: true,
autoScroll: true
}
});
layout.beginUpdate();
layout.add('north', new Ext.ContentPanel('header'));
layout.add('south', new Ext.ContentPanel('footer'));
layout.add('west', new Ext.ContentPanel('nav'));

var content = new Ext.ContentPanel('content',{fitToFrame:true});
layout.add('center', content);
layout.endUpdate();



Do the required datasource etc... for instatiating the grid



// create the Grid
var grid = new Ext.grid.Grid('results-grid', {
ds: ds,
cm: colModel,
autoExpandMin:100,
autoExpandMax:500,
autoExpandColumn: 'company'
});


Make a grid panel to contain the grid. Then set the 'content' div or the holder of the grid to be another BorderLayout



var gridpanel = new Ext.GridPanel(grid,{fitToFrame:true});


var contentLayout = Ext.BorderLayout.create({
center: {
margins:{left:0,top:0,right:0,bottom:0},
panels: [gridpanel]
}
}, 'content');
grid.render();


And the workaround is a force resize function, which you trigger when you need it. I have a hunch that the child BorderLayout does not inherit or register its event to its parent, and I'm not sure how to do this, so for now, I just forced it to resize.



function forceResizeGrid(){
var size = layout.getViewSize();
var w = size.width, h = size.height;
var centerW = w, centerH = h, centerY = 0, centerX = 0;

var rs = layout.regions;
var n = rs["north"], s = rs["south"], west = rs["west"], e = rs["east"], c = rs["center"];

if(n && n.isVisible()){
var b = n.getBox();
var m = n.getMargins();
b.width = w - (m.left+m.right);
b.x = m.left;
b.y = m.top;
centerH -= b.height + b.y + m.bottom;
}
if(s && s.isVisible()){
var b = s.getBox();
var m = s.getMargins();
b.width = w - (m.left+m.right);
b.x = m.left;
var totalHeight = (b.height + m.top + m.bottom);
b.y = h - totalHeight + m.top;
centerH -= totalHeight;
}
if(e && e.isVisible()){
var b = e.getBox();
var m = e.getMargins();
b.height = centerH - (m.top+m.bottom);
var totalWidth = (b.width + m.left + m.right);
b.x = w - totalWidth + m.left;
b.y = centerY + m.top;
centerW -= totalWidth;
}
if(west && west.isVisible()){
var b = west.getBox();
var m = west.getMargins();
b.height = centerH - (m.top+m.bottom);
b.x = m.left;
b.y = centerY + m.top;
var totalWidth = (b.width + m.left + m.right);
centerW -= totalWidth;
}

var m = layout.getRegion("center").getMargins();
var centerBox = {
x: centerX + m.left,
y: centerY + m.top,
width: centerW - (m.left+m.right),
height: centerH - (m.top+m.bottom)
};
var box = contentLayout.safeBox(centerBox);
contentLayout.getRegion("center").updateBox(box);
}

layout.addListener("regioncollapsed",forceResizeGrid);
layout.addListener("regionexpanded",forceResizeGrid);
layout.addListener("regionresized",forceResizeGrid);


The idea of the resize, is basically you can get from the region/panel the current size... determine the appropriate box width and height, then apply it to the child layout. This would not nessecarily work if your layout for the region is futher nested, you may need to tweak it to gather the nest box sizes for each level, and trickle down the events.

There's been a lot of requests regarding this even on other threads, so I hope this helps out.

vinod
2 Aug 2007, 10:44 AM
Thanks Acharis , Here is my situation.

HTML page is Like this following layout

North (Header region)
South(Footer region)
west (sidebar1 Collpasable )
east (side bar2 Collapasable)
Centre ( 3 regions North(combo box),South(page Bar), Centre (grid) )

when i Collapse (west )-sidebar1 everything works fine grid also resizes ,but when collapse (east) side bar2 grid will not resize it behaves like a fixed box.
Please help me why its not behaving just when i did in the west (side bar 2)Please how to load my Grid into Content panel when Grid is in Inner layout.

Thanks
vinod

acharis
2 Aug 2007, 9:06 PM
Vinod, I fixed the code a bit... kindly check the forceResizeGrid function again. apparently i need to recalculate the new width height depending on the components that are open.

The key is to have a BorderLayout nested for your grid. Not just a grid panel. This will be your tool to make sure that the grid has a way to expand to. The forceResizeGrid is an excerpt of their actual layout code. I just removed the centerX and centerY calculations, because your grid is centered in the BorderLayout anyway.

Basic logic...
1. Mother BorderLayout ---> addListener for regioncollapsed, regionresized and regionexpanded
so when your West and East panels change state, you can receive the event.

2. The grid in your "center" should have its own BorderLayout, well call it ContentLayout.

3. using something similar to the forceResizeGrid, recalculate what should be the actual size remaining for the center panel, and resize the Grid's ContentLayout.

Note: I havent tested this with a panel that has multiple components in the screen. I wish some ext-perts could somehow authenticate or correct my "hodge podge" code. As its not really pretty... and like what I said... just a workaround.

dot99
3 Aug 2007, 4:31 AM
I have placed grid panel into the "west" region of the BorderLayout. I have changed the forceResizeGrid to the next version: more universal, but probably more slow.


function forceResizeGrid(){
Ext.EventManager.fireResize();
}

vinod
6 Aug 2007, 5:23 AM
Thanks Acharis ,i am using editable grid . when i tried to place editable gird in a grid panel . it is becoming invisible in the page. Please some one can post the Code who used Editable grid in grid panel. when i look into gridpanel API , it looks like only for non editable grid.

Thanks
vinod

acharis
7 Aug 2007, 12:26 AM
Thanks Acharis ,i am using editable grid . when i tried to place editable gird in a grid panel . it is becoming invisible in the page. Please some one can post the Code who used Editable grid in grid panel. when i look into gridpanel API , it looks like only for non editable grid.

Thanks
vinod

Your welcome vinod. I tried it with the editable grid, and it works on my IE7 and firefox. Here's the changes I did with the code.



var colModel = new Ext.grid.ColumnModel([
{
id:'company',header: "Company", width: 160, sortable: true, locked:false, dataIndex: 'company',
editor: new Ext.grid.GridEditor(
new Ext.form.TextField(
{allowBlank: false}
)
)
},
{header: "Price", width: 75, sortable: true, renderer: Ext.util.Format.usMoney, dataIndex: 'price',
editor: new Ext.grid.GridEditor(
new Ext.form.TextField(
{allowBlank: false}
)
)
},
{header: "Change", width: 75, sortable: true, renderer: change, dataIndex: 'change',
editor: new Ext.grid.GridEditor(
new Ext.form.TextField(
{allowBlank: false}
)
)
},
{header: "% Change", width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange',
editor: new Ext.grid.GridEditor(
new Ext.form.TextField(
{allowBlank: false}
)
)
},
{header: "Last Updated", width: 85, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange',
editor: new Ext.grid.GridEditor(
new Ext.form.TextField(
{allowBlank: false}
)
)
}
]);


// create the Grid
var grid = new Ext.grid.EditorGrid('results-grid', {
ds: ds,
cm: colModel,
autoExpandMin:100,
autoExpandMax:500,
autoExpandColumn: 'company',
enableColLock:false
});

var gridpanel = new Ext.GridPanel(grid,{fitToFrame:true});


I'm working with Ext though in combination with Adobe AIR. And the double click or enter key does not trigger the edit mode inside AIR. In firefox and IE it works fine. Thats my new now.

kckchak
18 Aug 2007, 7:00 AM
Hi Vinod,
Use render() of grid when the region collapsed, resized and expanded events of layout. It has worked for me.

--Chakravarti