Reputation: 237
I am currently working on DataGrid
Component from Material-UI. Data can be displayed, but the inbuilt sorting is not working as expected. When I try to sort ASC/DESC it is sorting based on the first digit of the number. Please look into the picture below:
I have tried the same with fake API in CodeSandbox. It is working fine but in my application the sorting is acting different.
Then I have tried to add sortModel
(followed Material-UI Sorting docs) still it is acting the same. I haven't been able to find a solution in the docs.
const sortModel = [{ field: "canaryDeviceId", sort: "asc" }];
<div style={{ height: "90%", width: "100%" }}>
<DataGrid sortModel={sortModel} rows={rows} columns={columns} />
</div>
Upvotes: 7
Views: 8425
Reputation: 5461
You are suffering from the difference between alphabetic sort and natural sort.
The data grid allows you to implement your own sorting comparator, so you'd need to do that to get a natural sort algorithm.
In an alphabetic sort, you would get:
AA
AAA
AB
This is expected. Applied again to values with numbers, the following is correct (but not what you want):
A1
A11
A2
In a natural sort, the sort algorithm attempts to identify whole numbers within the text labels you're sorting, based on consecutive numberic digits being collapsed and treated as a number. You would get:
A1
A2
A11
Upvotes: -1
Reputation: 1261
Type Number value coming from API server side and will display a different value with modification
{ field: "controlTriggerLowerVal", headerName: "Lower Trigger", width: 150 ,type: "number",headerAlign: "left",
renderCell: (cellValues) => {
return <> {cellValues.row.calculateLowerTrigger} </>;
},flex:1,align: 'left'
Another way to write custom sort , also handles null and space:
nullSpaceHandlingSortComparator = (
v1,
v2,
cellParams1,
cellParams2
) => {
const sortModel = cellParams1.api.getSortModel();
const sortColumn = sortModel.find(
(sm) => sm.field == cellParams1.field
);
if (sortColumn && sortColumn.sort == "desc") {
if ((v1 == null && v2 == null) || (v1 == "" && v2 == "")) {
return -1;
}
if ((v1 == null) || (v1 == "")) {
return -1;
}
if ((v2 == null) || (v2 == "")) {
return 1;
}
return v1 - v2;
}else{
if ((v1 == null && v2 == null) || (v1 == "" && v2 == "")) {
return 0;
}
if ((v1 == null) || (v1 == "")) {
return 1;
}
if ((v2 == null) || (v2 == "")) {
return -1;
}
return v1 - v2;
}
};
{ field: "controlTriggerLowerVal", headerName: "Lower Trigger", width: 150 ,type: "number",headerAlign: "left",
renderCell: (cellValues) => {
return <> {cellValues.row.calculateLowerTrigger} </>;
},flex:1,align: 'left',
sortComparator: this.nullSpaceHandlingSortComparator,
}
Upvotes: 0
Reputation: 81400
I think DataGrid
columns by default use string comparator, if you want to sort numeric column, try setting the type to 'number'
:
{
field: "deviceID",
headerName: "Canary DeviceID",
type: "number",
},
Then I have tried to add sortModel (followed Material-UI Sorting docs) still it is acting the same.
sortModel
only describes the sorting state of DataGrid
so I doubt it will solve your problem.
Upvotes: 12