I am using Material UI DataGrid and one of my columns contains dates. The Material UI documentation says to set the type to "date" in the column array, which I have done:
{
field: "submittedAt",
headerName: "Submitted",
minWidth: 150,
flex: 2,
type: "date",
headerClassName: "tableHeader",
cellClassName: "hoverPointer"
}
I am then converting my timestamp to MM/dd/yyyy format using Luxon
if (r.data().submittedAt) {
const d = DateTime.fromMillis(r.data().submittedAt.toMillis());
requestedDate = d.toFormat('MM/dd/yyyy')
}
and then using requestedDate
to set the value of the cell in the column. When I sort the data, the column is still sorting by a string parator instead of by date:
I'm not sure what I'm doing wrong, and I can't seem to find much support in the documentation or in previous posts. I know I could set the date to yyyy/MM/dd so the string parator works, but I don't want that format rendered for readability purposes. I also need the column to be dynamically sortable by the user, so server-side sorting won't help me out either. Thanks in advance for any help.
I am using Material UI DataGrid and one of my columns contains dates. The Material UI documentation says to set the type to "date" in the column array, which I have done:
{
field: "submittedAt",
headerName: "Submitted",
minWidth: 150,
flex: 2,
type: "date",
headerClassName: "tableHeader",
cellClassName: "hoverPointer"
}
I am then converting my timestamp to MM/dd/yyyy format using Luxon
if (r.data().submittedAt) {
const d = DateTime.fromMillis(r.data().submittedAt.toMillis());
requestedDate = d.toFormat('MM/dd/yyyy')
}
and then using requestedDate
to set the value of the cell in the column. When I sort the data, the column is still sorting by a string parator instead of by date:
I'm not sure what I'm doing wrong, and I can't seem to find much support in the documentation or in previous posts. I know I could set the date to yyyy/MM/dd so the string parator works, but I don't want that format rendered for readability purposes. I also need the column to be dynamically sortable by the user, so server-side sorting won't help me out either. Thanks in advance for any help.
Share Improve this question asked Jan 16, 2022 at 20:38 RyanYRyanY 6751 gold badge8 silver badges21 bronze badges4 Answers
Reset to default 3What I did:
- in the data / the back end response, return an ISO timestamp that the DataGrid understands already (e.g. "2022-09-12T10:01:08+0200")
- just change the way that timestamp is displayed to the user.
This way, the adjustments that you need to make are minimal (just the rendering code)
const dateFormattingOptions: Intl.DateTimeFormatOptions = {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
};
function renderDate(checkTimeAndDate: any) {
if (!checkTimeAndDate) {
return '';
}
return new Date(checkTimeAndDate).toLocaleDateString(
'de-DE',
dateFormattingOptions
);
}
const columns: GridColDef[] = [
// ...
{
field: 'myTimeAndDateField',
headerName: 'My Time and Date',
width: 250,
type: 'dateTime',
renderCell: (params: GridRenderCellParams<MyDataTypeWithADateField>) =>
renderDate(params.row.myTimeAndDateField)
},
// ...
];
return (<DataGrid
rows={myData}
columns={columns}
// ...
/>);
Testing:
test('the data table renders timestamps, formatted for Germany', async () => {
// ...
render(<MyComponent />);
expect(findDataFieldValue('myTimeAndDateField')).toBe('12.09.2022, 10:01:08');
});
function findDataFieldValue(dataField: string): string | null | undefined {
// material UI makes this into a div - I need to get conceptual table cell instead
const element: HTMLElement | null = document.querySelector<HTMLElement>(
"div[role='cell'][data-field='" + dataField + "']"
);
return element?.textContent;
}
Test data:
export const testData: MyDataTypeWithADateField = {
// ...
myTimeAndDateField: '2022-09-12T10:01:08+0200',
// ...
};
Render columns you can define like this.
const columns = [
{
field: 'date', headerName: 'Date', flex: 1, headerClassName: 'data-grid-header', type: 'date',
renderCell: (params) =>
renderDate(params.row?.date)
}
];
Render function was used with date-fns in order to convert to format which i needed
//import
import {format} from 'date-fns'
function renderDate(date) {
if (!date) {
return '';
}
return format(new Date(date), 'MM/dd/yyyy');
}
Then a sortModel was used for date field sorting
<DataGrid
className={'data-grid-data-row'}
sx={{fontSize: '12px'}}
rows={data}
autoHeight {...data}
columns={columns}
pageSize={pageSize}
rowsPerPageOptions={[10, 25, 50]}
onCellClick={(params) => onRowClick(params)}
initialState={{
sorting: {
sortModel: [{field: 'date', sort: 'desc'}],
}
}}/>
This code segment accepts the timestamp and then sort them by date and render value according to the date time format we have defined in the function.
In my case, the issue was that my row ID was duplicate.
i did resolved that problem ording the data of Datagrid in server and then i shorted the rows with sortComparator paring the id's of each cell.
sortingOrder: ['desc', 'asc'],
sortComparator: (v1, v2, param1, param2) =>{
return param1.id - param2.id;
}
an example