Question

I have an Ext GroupingStore on a list of orders. One of the columns is a DateTime. I would like the user to be able to group by the DateTime column and have all days under one group. At the moment, each date, hour, minute and second is one group... not very useful :-)

Any way short of two columns to accomplish this?

Was it helpful?

Solution

You can modify a GroupingView method to accomplish this.

First create the GroupingView object:

var gview = new Ext.grid.GroupingView({
        forceFit: true,
        groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})'
    });

Then modify the (in fact "private") method:

gview.getGroup = function(v, r, groupRenderer, rowIndex, colIndex, ds){
    // colIndex of your date column
if (colIndex == 2) {
            // group only by date
    return v.format('m.d.Y');
}
    else {
 // default grouping
     var g = groupRenderer ? groupRenderer(v, {}, r, rowIndex, colIndex, ds) : String(v);
     if(g === ''){
         g = this.cm.config[colIndex].emptyGroupText || this.emptyGroupText;
     }
     return g;
    }
};

Then apply the View to the grid:

var grid = new Ext.grid.GridPanel({
 ...
 view: gview,
 ...
});

Ah well, a little proof of concept (Click on sort 'Last Updated')

Demo

OTHER TIPS

I think you can specify the date format when you are defining the record type for the store. It may solve your problem.

Something like

    var reader = new Ext.data.JsonReader(
    fields:[{
        type: 'date',
        dateformat: 'd M Y'
    },{
        .............
        ..............
    },
    .............
    .............
    ]
)

var store = new Ext.data.Store({
    reader: reader,
    data: []
})

Tarnschaf's answer was correct, I just thought I would post my final, modified version of his code for completness. This was how I ended up doing it. Thanks Tarnschaf!

g.view.getGroup = g.view.getGroup.wrap(function(normal,v, r, groupRenderer, rowIndex, colIndex, ds)
{
    var cm = g.getColumnModel();
    var id=cm.getColumnId(colIndex);
    var col=cm.getColumnById(id);

    if(col.renderer == formatDateTime)
    {
        v = (new Date(v)).format('m/d/yy');
        groupRenderer = formatDate;
    }

    return normal(v, r, groupRenderer, rowIndex, colIndex, ds);
});

where g is the GridView. I found that by using g.view.getGroup.wrap I could keep the previous function intact, and only modify the parameters as Tarnschaf's answer did. Also, this method works even if the columns are reordered -- there's no colIndex hard coded in. Furthermore, it automatically applies itself to every column which has a renderer of formatDateTime (my date/time formating function) and switches those to the formatDate groupRenderer so the group headings look cleaner.

Do you actually need to reference the time part of the date? If not, you could use a convert function on the field to call clearTime() on the date object.

In your grid column definition, define a groupRenderer config:

{
  groupRenderer : function(v, u, r, row, col, store) {                        
     return //your custom group value
   }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top