I am using UI-grid, and I have a bunch of JS date objects like so:
"dob": new Date('1942-11-19')
I want to be able to filter the column by date when you click the "sort ascending/descending" buttons. As such, I have set the colDef
up like so:
{
field: 'dob'
, displayName: 'D.O.B.'
, width: '130'
, editableCellTemplate: '<div><form name="inputForm"><input type="INPUT_TYPE" ng-class="\'colt\' + col.uid" ui-grid-editor ng-model="MODEL_COL_FIELD" style="border-bottom-color: #74B3CE; border-bottom-width: 2px;"></form></div>'
, headerCellClass: $scope.highlightFilteredHeader
, cellTemplate: '<div class="ui-grid-cell-contents" >{{grid.getCellValue(row, col)| date:\'MM-dd-yyyy\'}}</div>'
, cellFilter: 'date'
, type: 'date'
},
however, the column simply does not sort correctly. I even tried to set up a function to sort it from an external button like so:
function mostRecent(){
console.log('clicked mostRecent');
$scope.gridApi.grid.sortColumn(
$scope.gridApi.grid.getColumn('dob'), uiGridConstants.DESC
);
$scope.gridApi.grid.notifyDataChange(uiGridConstants.dataChange.ALL); //this line updates the rest of the columns accordingly
};
But it also causes a mish-mush sort that is not correct. Does anyone know what the issue is? I thought it might have to do with my cellTemplate
, but after removing the template, there wasn't a difference...
Yes you are right, ui-grid doesn't support sorting of Date type columns.
However you can define a sortingAlgorithm
in the columnDef
.
Here is how your column definition should look like:
...
columnDefinition.sortingAlgorithm = function (firstDateString, secondDateString) {
var dateFormat = 'YYYY-MM-DD';
return function (firstDateString, secondDateString, dateFormat) {
if (!firstDateString && !secondDateString) {
return 0;
}
if (!firstDateString) {
return 1;
}
if (!secondDateString) {
return -1;
}
var firstDate = $window.moment(firstDateString, dateFormat);
if (!firstDate.isValid()) {
throw new Error('Invalid date: ', firstDateString);
}
var secondDate = $window.moment(secondDateString, dateFormat);
if (!firstDate.isValid()) {
throw new Error('Invalid date: ', secondDateString);
}
if (firstDate.isSame(secondDate)) {
return 0;
} else {
return firstDate.isBefore(secondDate) ? -1 : 1;
}
};
};
...
Please note that in this example Moment.js is used. It is a very useful library so you might probably find also another place in your project where to use it.