Ext JS GroupingStore group DateTime column by just date?
-
22-07-2019 - |
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?
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')
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
}
}