PDA

View Full Version : Ext.ux.AnimalGridView simple GridView implementation



Animal
10 Mar 2008, 3:15 AM
This implementation of GridView uses DIVs to lay the Grid out instead of stacked <table> elements. It's a much less complex document, so I imagine it will be a little faster. It's a copy and paste job on the Ext.grid.GridView with different templates and element selection.

This means more accurate column width handling because browsers "crunch" table widths when space gets short, so the standard Ext GridView starts losing track between header cell widths and body cell widths when there are many columns.

It also means you can have lines between grid rows again.

This uses table-styled DIVs on Mozilla:

http://www.sitepoint.com/blogs/2008/02/28/table-based-layout-is-the-next-big-thing/

And float:left DIVs on Opera and IE7

Those are the only browsers I have access to.

The attached ZIP file unzips into examples/grid, and takes the place of the array-grid example. The necessary CSS is embedded in the HTML file.

5245

jsakalos
10 Mar 2008, 9:16 AM
Hi Animal,

perfect idea, could lead also to better grid performance.

I found one problem though; I you try to hide/show a column (I've tested Company) the width of headers and cells gets out of sync. I suspect it's original GridView bug - I've already reported it in FogBugz. After resizing the column, all subsequent hide/show cycles work fine.

jack.slocum
10 Mar 2008, 10:59 AM
Sweet, I've been meaning to create a GridViewLite myself. I think you might want to include a note that things like dynamic row heights and expander rows won't work with this version before the bug reports start flowing. ;)

It reminds me a lot of the .33 grid markup.

mystix
10 Mar 2008, 11:26 AM
@animal, =P~

@saki -- fogbugz? what happened to the xtracker in the pipeline :-?

Animal
10 Mar 2008, 11:33 AM
I'll do some testing tomorrow with dynamic row heights and expanders. I should be able to plug that class into any of the examples. No reason why I shouldn't be able to make everything work.

I've started using this in our app because some Grids have a lot of columns.

jack.slocum
10 Mar 2008, 6:06 PM
I'll do some testing tomorrow with dynamic row heights and expanders.

The layout:table should work fine in FF but in IE the floated divs won't have a uniform height.

The other idea I had was to create a lightweight subclass of DataView called ListView. It wouldn't have the capabilities of the GridView3, instead would be a lightweight alternative.

luv2hike
13 Mar 2008, 11:26 AM
I was trying to use this in correlation to the AutoGrid extension and it displays all columns vertically instead of horizontally.


queryGrid = new Ext.ux.AutoGridPanel(
{
id: 'qgrid',
title: 'Query Results',
renderTo: Ext.getBody(),
layout: 'fit',
autoWidth: true,
loadMask: true,
stripeRows: false,
trackMouseOver: true,
frame: true,
hideMode: 'offsets',
view: new Ext.ux.AnimalGridView(),
store: new Ext.data.Store(
{
proxy: new Ext.data.HttpProxy(
{
url: 'secure/executeQuery',
method: 'POST'
}),
reader: new Ext.data.JsonReader()
}),
tbar: [
{ text:"Copy", tooltip:"Prepares selected data for copy/pasting into a spreadsheet.",
handler:function()
{
var arr = queryGrid.getSelectionModel().getSelections();
var cm = queryGrid.getColumnModel();
var str = '<table border="1" style="border-collapse:collapse"><tr>';

// headers
for(var j=0; j < cm.getColumnCount(); j++)
{
if(!cm.isHidden(j)) {
str=str+'<td>'+cm.getColumnHeader(j)+'</td>';
}
}
str=str+'</tr>';

// rows
for(var i=0; i < arr.length; i++)
{
str=str+'<tr>';

// each col
for(var j=0; j < cm.getColumnCount(); j++)
{
if(!cm.isHidden(j)) {
str=str+'<td>'+arr[i].get(cm.getDataIndex(j))+'</td>';
}
}
str=str+'</tr>';
}
str=str+'</table>';

var win = new Ext.Window({
html: str,
title: 'Highlight and Copy',
modal: true,
autoScroll: true,
width: 600,
height: 400
});
win.show();
}
}
]
});

// Query viewer form
queryForm = new Ext.form.FormPanel(
{
region: 'north',
id: 'queryform',
height: 200,
labelAlign: "top",
bodyStyle: blankBgStyle,
items: [
{
fieldLabel: 'Enter Query',
labelStyle: 'font-weight:bold;',
xtype: 'textarea',
name: 'sqlQuery',
allowBlank: false,
width: tabPanelWidth,
height: 180,
emptyText: 'Type a valid SQL query here then click Submit'
}],
buttons: [
{
text: 'Submit',
tooltip: 'Click to submit the query.',
handler: function()
{
// make results visible
var southPanel = Ext.getCmp("southPanel");
southPanel.getLayout().setActiveItem('qresults');
southPanel.expand();

// reconfigure the grid with the results
queryGrid.show();
queryGrid.getSelectionModel().clearSelections();
queryGrid.getStore().load({ params:{ sqlQuery:queryForm.getForm().getValues().sqlQuery } });
}
},
{
text: 'Clear',
tooltip: 'Click to clear the query and results.',
handler: function()
{
queryForm.getForm().reset();
queryGrid.hide();
queryGrid.getSelectionModel().clearSelections();
Ext.getCmp("southPanel").getLayout().setActiveItem('qresults');
}
}]
});

luv2hike
13 Mar 2008, 12:51 PM
Actually, I removed the use of AutoGrid and use GridPanel with its reconfigure method instead. I still cannot get the columns to display across instead of down when setting the column model from a JSON reader.


// Query results grid
queryGrid = new Ext.grid.GridPanel(
{
id: 'qgrid',
title: 'Query Results',
renderTo: Ext.getBody(),
layout: 'fit',
autoWidth: true,
loadMask: true,
stripeRows: false,
trackMouseOver: true,
frame: true,
hideMode: 'offsets',
view: new Ext.ux.AnimalGridView(),
cm: new Ext.grid.ColumnModel([]),
store: new Ext.data.Store(
{
proxy: new Ext.data.HttpProxy(
{
url: 'secure/executeQuery',
method: 'POST'
}),
reader: new Ext.data.JsonReader()
}),
tbar: [
{ text:"Copy", tooltip:"Prepares selected data for copy/pasting into a spreadsheet.",
handler:function()
{
var arr = queryGrid.getSelectionModel().getSelections();
var cm = queryGrid.getColumnModel();
var str = '<table border="1" style="border-collapse:collapse"><tr>';

// headers
for(var j=0; j < cm.getColumnCount(); j++)
{
if(!cm.isHidden(j)) {
str=str+'<td>'+cm.getColumnHeader(j)+'</td>';
}
}
str=str+'</tr>';

// rows
for(var i=0; i < arr.length; i++)
{
str=str+'<tr>';

// each col
for(var j=0; j < cm.getColumnCount(); j++)
{
if(!cm.isHidden(j)) {
str=str+'<td>'+arr[i].get(cm.getDataIndex(j))+'</td>';
}
}
str=str+'</tr>';
}
str=str+'</table>';

var win = new Ext.Window({
html: str,
title: 'Highlight and Copy',
modal: true,
autoScroll: true,
width: 600,
height: 400
});
win.show();
}
}
]
});

queryGrid.store.on('metachange', function(store, meta)
{
var cm = new Ext.grid.ColumnModel(meta.fields);
queryGrid.reconfigure(store, cm);
});

// Query viewer form
queryForm = new Ext.form.FormPanel(
{
region: 'north',
id: 'queryform',
height: 200,
labelAlign: "top",
bodyStyle: blankBgStyle,
items: [
{
fieldLabel: 'Enter Query',
labelStyle: 'font-weight:bold;',
xtype: 'textarea',
name: 'sqlQuery',
allowBlank: false,
width: tabPanelWidth,
height: 180,
emptyText: 'Type a valid SQL query here then click Submit'
}],
buttons: [
{
text: 'Submit',
tooltip: 'Click to submit the query.',
handler: function()
{
// make results visible
var southPanel = Ext.getCmp("southPanel");
southPanel.getLayout().setActiveItem('qresults');
southPanel.expand();

// reconfigure the grid with the results
queryGrid.show();
queryGrid.getSelectionModel().clearSelections();
queryGrid.getStore().load({ params:{ sqlQuery:queryForm.getForm().getValues().sqlQuery } });
}
},
{
text: 'Clear',
tooltip: 'Click to clear the query and results.',
handler: function()
{
queryForm.getForm().reset();
queryGrid.hide();
queryGrid.getSelectionModel().clearSelections();
Ext.getCmp("southPanel").getLayout().setActiveItem('qresults');
}
}]
});

Animal
13 Mar 2008, 2:09 PM
It needs the CSS to tell Gecko to display DIVs as table-cells and to tell IE to float them left.

BTW, I gave up on row expander. I couldn't get it to work right. Best leave that to the table view.

luv2hike
13 Mar 2008, 3:16 PM
Bingo. I should've caught that! Anyway that got it for the most part. However, it broke down - meaning the column headers were not the correct widths and did not align over the data - for wide tables; in my case, 253 columns. Using the standard table based grids do, though VERY slowly. Your div version, though not lined up for that many columns, loaded in a tenth of the time. Cool.

Animal
14 Mar 2008, 2:22 AM
Are you using the latest code from post 1?

I have 44 columns in the widest Grid, and it works OK.

luv2hike
14 Mar 2008, 6:32 AM
I believe so. I downloaded the zip file attached to that post yesterday. It also works fine for me with 30 or so columns, but 200+ is a different animal, no pun intended. ;) I am not using autofit as I want it to scroll horizontally, so maybe that's it? Or remember, I am dynamically updating the column model from a JSON response from the server each time (using GridPanel.reconfigure) so maybe that is the culprit?

If you can figure this out for really wide grids, that would be terrific. I do have a working solution now using the standard table-based grids, but your's is a ton faster so I'd love to switch to it.

mystix
14 Mar 2008, 7:16 AM
@Animal, neat work!

i used the latest code from post 1 though, and found the following funky things:

funky thing 1 - screencast (http://screencast.com/t/D40KoDFRAc5)
funky thing 2 - screencast (http://screencast.com/t/s6upXWyV)

Animal
14 Mar 2008, 7:28 AM
That's weird. I see that when I run it standalone in the array-grid example, but in my app, I can hide and show columns, and it relays perfectly!!??

mystix
14 Mar 2008, 8:12 AM
:-? odd... you're probably calling an AnimalGridView.refresh() or something, somewhere...???

did you see the other funky thing happening when sorting?
just keep sorting a single column and the grid literally heads south...

Animal
15 Mar 2008, 5:17 AM
It's probably a bit flawed being a copy/paste job from the Ext GridView. I probably haven't converted everything over to select the correct elements from the generated DOM yet. I'l give it some more work when I have time. Believe it or not, I'm having to turn down work... which is a nice problem to have really!