PDA

View Full Version : Can't group on column with a custom renderer



glaforge
22 Feb 2008, 7:41 AM
Hello,

I've searched the documentation and forums, but couldn't find anything so far, so I'm raising the question here.

I've got a grid panel with a grouping store.
All works fine: whatever column I choose to group on, the grouping is done.

However, when I specify a custom renderer for one of my column, with something like that:

{ header: "Incident", dataIndex: 'number', width: 250, sortable: true, renderer: formatIncident }
Then, when I group on this column, even for lines with the same value in it, there's one group per line!

See the attached screenshot.
You'll see the grouping isn't done on the company name (here: G2One), although the grouping supposed to be done on this column.

Is there something special to make the grouping work correctly here when there's a custom renderer?

Thanks in advance for your help.

Guillaume

evant
22 Feb 2008, 7:44 AM
Odd. Can we see some more of your code?

para
22 Feb 2008, 7:44 AM
You may have create another field in the store, make it's values the rendered values, and then make the columnModel use that field instead of the original.
Are you displaying only? or are you allowing editing? I think if it's only for display it should work fine. Allowing editing may make it a bit more difficult....

glaforge
22 Feb 2008, 9:07 AM
Odd. Can we see some more of your code?

Sure!

So, I've got a renderer method that I'm using for rendering my company column:



function formatCompanyName(val, cell, record) {
return "<a href='../company/show/" + record.id + "'>" + val + "</a>";
}


I define the data record I'm using:



var incidentRecord = new Ext.data.Record.create([
{ name: 'id' },
{ name: 'number' },
{ name: 'queue' },
{ name: 'requestor' },
{ name: 'company' },
{ name: 'priority' },
{ name: 'status' },
{ name: 'created', type: 'date' }
]);


I've got a JSON reader:



var reader = new Ext.data.JsonReader({
root: 'incidents',
totalProperty: 'totalCount',
id: 'id'
}, incidentRecord);


And here's my data store:



var mainStore = new Ext.data.GroupingStore({
reader: reader,
url: 'listJson',
sortInfo: { field: 'created', direction: "DESC" },
remoteSort: true,
groupField: 'queue'
});


The URL points to a controller of my web framework (Grails (http://grails.org)), that renders JSON content.

And here's the definition of my grid panel


var mainGrid = new Ext.grid.GridPanel({
id: 'incidentGrid',
title: 'All incidents',
renderTo: mainContainer,
store: mainStore,
columns: [
{ header: "Incident", dataIndex: 'number', width: 250, sortable: true, renderer: formatIncident },
{ header: "Queue", dataIndex: 'queue', width: 100, sortable: true },
{ header: "Requestor", dataIndex: 'requestor', width: 100, sortable: true },
{ header: "Company", dataIndex: 'company', width: 50, sortable: true, renderer: formatCompanyName },
{ header: "Priority", dataIndex: 'priority', width: 50, sortable: true },
{ header: "Status", dataIndex: 'status', width: 50, sortable: true },
{ header: "Date created", dataIndex: 'created', width: 150, sortable: true },
],

view: new Ext.grid.GroupingView({
forceFit: true,
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "incidents" : "incident"]})'
}),

stripeRows: true,
monitorResize: true,
autoHeight: true,
autoExpandColumn: 1,
width: '100%',
sm: mainSm,
bbar: new Ext.PagingToolbar({
pageSize: 10,
store: mainStore,
displayInfo: true,
displayMsg: 'Page {0}-{1} of {2} incidents',
emptyMsg: "No incident"
})
});


You'll notice the renderer used for the company column, my paging toolbar, and also the grouping view I'm using.

Perhaps there's really something obvious I'm missing?
When I don't set the renderer, everything works fine, but with the renderer, for some reason, every single line is grouped into one group.

glaforge
22 Feb 2008, 9:09 AM
You may have create another field in the store, make it's values the rendered values, and then make the columnModel use that field instead of the original.
Are you displaying only? or are you allowing editing? I think if it's only for display it should work fine. Allowing editing may make it a bit more difficult....

Fortunately, at least for the time being, I'm not doing any in-place editing :)

I'll try to investigate your solution.
It feels like a workaround to something that should be working, but I may perhaps simply missing the obvious.

para
22 Feb 2008, 9:40 AM
I think my solution won't fix it.

I've looked at it a bit further, and GroupingView works like this:

When grouping by a column,
the underlying store is sorted by that dataIndex
It then rerenders the grid, row by row (like usual)
when it comes across a row with a different value than the row before it ******
it inserts the group header.


Notice the *****. The grouping is based on the RENDERED value of the cell. This means that when you render it to include a link to the record id or something, the values will be different.
The solution is to make your links differently. You may need a combination of css and the gridPanel's 'cellclick' event. You can CSS your cell to look the same as a link using the renderer, and then do the actual link functionality in a javascript function.

function formatCompanyName(val, cell, record) {
return '<a href="#">' + val + '</a>';
}

// this may not be perfect, but it's close...

gridPanel.on('cellclick', function(gridpanel, rowIndex, columnIndex, e) {
if(gridPanel.colModel.config[columnIndex].dataIndex == 'company') {
window.open('../company/show/' + rowIndex);
}
});

glaforge
22 Feb 2008, 1:41 PM
I think my solution won't fix it.

I've looked at it a bit further, and GroupingView works like this:

When grouping by a column,
the underlying store is sorted by that dataIndex
It then rerenders the grid, row by row (like usual)
when it comes across a row with a different value than the row before it ******
it inserts the group header.


Notice the *****. The grouping is based on the RENDERED value of the cell. This means that when you render it to include a link to the record id or something, the values will be different.
The solution is to make your links differently. You may need a combination of css and the gridPanel's 'cellclick' event. You can CSS your cell to look the same as a link using the renderer, and then do the actual link functionality in a javascript function.

Okay, thanks for the explanation, I understand this situation better now.
By tweaking your code snippet, I think I can make it work.

However, I wanted to highlight the fact that there's a remoteGroup option on GroupingStore which asks the backend to do the grouping remotely. This is interesting as the grouping will be done on the whole dataset, and not just the visible paged set of record. But my current backend code doesn't (yet) support remote grouping.

So, I think that using remoteGroup could work as a general solution, since the grouping is done remotely, so even with a custom renderer, that'd do it.