views:

2118

answers:

4

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?

A: 

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 the grouping I didn't need to reference it but the column still needed to display it. Tarnschaf hit the nail on the head. Group by day, but still show time in the column.
Josh
+2  A: 

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: []
})
Arun P Johny
I didn't even try this -- it might work. I saw the other answer and instantly knew it was what I was looking for.
Josh
+3  A: 

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

Tarnschaf
Awesome, that's perfect!
Josh
I modified this a bit, see my own answer. You get the points though because I really just cleaned up your code a bit -- the logic/method is yours. Thanks again!
Josh
+1  A: 

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.

Josh
cool :) if you now change the hardcoded m/d/yy to the default local setting used by Ext, it should be a great and generic solution to this problem! thanks for the points..
Tarnschaf