PDA

View Full Version : Adding a grid to existing layout



kadams54
3 May 2007, 8:54 AM
I have a page that includes two scripts: one script is reused across the app to create the layout (a derivative of the complex layout example). The other script is specific to that page and builds the data grid (a derivative of the inline editing example) for display in the center area of the layout. It should fill the center area and resize as the window resizes or when the user expands the west region.

Two questions...

Based on what I've come across in docs and on the forum, it sounds like I need to:


Build the grid
Add it to a GridPanel
Add the GridPanel to a BorderLayout (pretty much following the inline editing example up to this point)
Add the BorderLayout to a NestedLayoutPanel
Add the NestedLayout to my app's BorderLayout


Is that correct?

Since my grid currently lives in a separate script (and scope) from my app layout, how can the grid script retrieve said layout object and and add itself to the center region?

Here are the trimmed-down code samples:

Layout.js



var Layout = {
init : function(){
layout = new Ext.BorderLayout(document.body, {
hideOnLayout: true,
north: { ... },
west: { ... },
south: { ... },
center: { ... }
});

layout.beginUpdate();
layout.add('north', new Ext.ContentPanel('nav', 'Navigation'));
layout.add('south', new Ext.ContentPanel('status', {title: 'Status', closable: true}));
layout.add('west', new Ext.ContentPanel('search', {title: 'Search'}));
layout.add('center', new Ext.ContentPanel('content', {title: 'Content', closable: false}));
layout.endUpdate();
}
};

Ext.onReady(function() {
Layout.init();
});


CipGrid.js



var CipGrid = {
init: function() {
var grid = this.createGrid('editor-grid');

// create the grid panel
var gridPanel = new Ext.GridPanel(grid);

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

var nestedPanel = new Ext.NestedLayoutPanel(layout, 'CIP Grid');
// I THINK THERE IS WHERE IT NEEDS TO BE ADDED TO THE APP LAYOUT
// layout.add('center', nestedPanel);

// render it
grid.render();

// add the grid's toolbar
var gridHead = grid.getView().getHeaderPanel(true);
var tb = new Ext.Toolbar(gridHead, [{
text: 'Add CIP',
handler : function(){
var p = new Cip({ ... });
grid.stopEditing();
ds.insert(0, p);
grid.startEditing(0, 0);
}
}]);
},

createGrid: function(id) {
var fm = Ext.form, Ed = Ext.grid.GridEditor;

// the column model has information about grid columns
// dataIndex maps the column to the specific data field in
// the data store (created below)
var cm = new Ext.grid.ColumnModel([{ ... }, ... ]);

// by default columns are sortable
cm.defaultSortable = true;

// this could be inline, but we want to define the CIP record
// type so we can add records dynamically
var Cip = Ext.data.Record.create([ { ... }, ... ]);

// create the Data Store
var ds = new Ext.data.Store({
// load using HTTP
proxy: new Ext.data.HttpProxy({url: 'cips.xml'}),

// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have a "cip" tag
record: 'cip'
}, Cip)
});

// create the editor grid
var grid = new Ext.grid.EditorGrid(id, {
ds: ds,
cm: cm,
enableColLock:false
});

// trigger the data store load
ds.load();

return grid;
}
};

Ext.onReady(function() {
CipGrid.init();
});


And finally the HTML:



<div id="content" class="x-layout-inactive-content">
<div id="grid-panel">
<div id="editor-grid"></div>
</div>
</div>

tryanDLS
3 May 2007, 9:22 AM
The grid script shouldn't know about the layout - that ties the grid functionality to a single target. Instead the layout script should be requesting the grid script (which just builds the grid) and putting the grid into the gridpanel.

kadams54
3 May 2007, 9:57 AM
Hmm, my approach may need some tweaking...

Some background info: I'm doing some proof-of-concept conversions of existing screens into an Ext-driven UI. In general I'd like to use Ext to "spice up" existing DOM elements, rather than generating them from scratch.

My original thought was to create a base layout (Layout.js) that would be re-used across all of the screens. Each screen would be responsible for populating (either on the server side by generating HTML, or on the client side via JS) the layout with the screen-specific information. That is, the screen-specific content would have to be aware of the layout rather than vice versa.

Is that the wrong approach to take with Ext's layout? If so, how could I create a base layout reusable across different HTML files but also make the layout aware of the screen-specific content it needs to display?

I should also clarify that this particular grid (CipGrid) would only be used in the center area of the base layout, so I'm not sure tying it to that target is really all that bad.

kadams54
4 May 2007, 2:33 PM
Some closure on this issue: I took my cue from ReaderLayout and created a BaseLayout that minimizes the amount of layout code that needs to be duplicated across screens within the app. A screen-specific javascript is responsible for populating the BaseLayout with the appropriate content (including, in this case, a grid):



var Cip = function() {
return {
init: function() {
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

var gridPanel = CipGrid.getPanel();

var layout = new BaseLayout({east: false, preview: false});
var CP = Ext.ContentPanel; // shortcut for adding

layout.beginUpdate();
layout.add('north', new CP('nav', 'Navigation'));
layout.add('south', new CP('status', {title: 'Status', closable: true}));
layout.add('west', new CP('search', {title: 'Search'}));

layout.regions.listView.add(gridPanel);
layout.endUpdate();
}
};
}();

Ext.onReady(Cip.init, Cip);

mschering
19 Jun 2007, 6:06 AM
This is a nice solution, but what if you don't want to construct the grid unless someone clicks the panel?

I want to load the grid only if the panel tab is clicked. Does anyone know how to pull this off?

kadams54
19 Jun 2007, 6:44 AM
Seems to me that if that's the case, then you just defer grid creation until the panel's click event. This is a guess since I haven't had a chance to test it, but it seems like the click eventhandler would look something like:



var gridPanel = CipGrid.getPanel();

layout.beginUpdate();
layout.regions.listView.add(gridPanel);
layout.endUpdate();


The interesting part (for me, because I have no experience with it) would be the layout variable. Depending on where you put the click eventhandler function (in the Cip module or in some other module) you'd need someway to pass the initialized layout into that function; callback, private instance variable inside the Cip module, etc.

mschering
19 Jun 2007, 6:51 AM
You can't add the grid like that because the grid must be specified in the GridPanel constructor.

Or am I wrong and can a gridpanel's grid be set after the gridpanel is added to a layout?

mschering
22 Jun 2007, 12:35 AM
I have the same problem with toolbars of contentpanels.

dscoular
1 Nov 2007, 3:38 AM
Hi,
I've been banging my head against the same issue all week. I'm stuck with Ext 1.1.1.

I've been searching the forums and asking dumb questions on irc... but nothing.

I don't know the size of my grids or the columns they are going to have at layout
time. So I create a BorderLayout with a north region and add two ContentPanels and that
gives me two nice tabs (which I guess maybe promotes the ContentPanels into
TabPanelsItems). I want to ensure the left most one is active and then make two
callbacks.

Anyway, now I make 2 callbacks to get some JSON definitions which tell me the
columns and data for my 2 grids... but a grid wants to know it's containing element...
do I give it my ContentPanel or a child of the panel ?

When I try either of those nothing seems to get added. I suspect it breaks because
what I really needs is a GridPanel not a ContentPanel (or TabItemPanel or whatever
happens when tabs automagically make themselves).

What I really want to know is how to set the content of one of the tabs to be a GridPanel
so I get the size of the grids managed when the user moves the splits in the layouts.

Can someone please help... examples hugely appreciated...

Cheers,

Doug