Munna
Munna

Reputation: 207

How to sort Date/Time column in angular 4 material sort?

I'm using angular material table and using matSort for sorting. But it's not sorting the dates/time column. It takes the datetime column values as strings.

How to sort date/time column in angular 4 material ?

My json will look like this

 {
        "name": "Rule Test 5",
        "time": "2017-11-17T08:34:32",
        "version": 1,
        "status": "SAVED"
    }, {
        "name": "Availability Adjustment",
        "time": "2017-11-17T10:13:27",
        "version": 1,
        "status": "SAVED"
    }, {
        "name": "Class suppression",
        "time": "2017-11-17T11:18:44",
        "version": 1,
        "status": "SAVED"
    }

my table look like this

-------------------------------
name | version | status | date |
-------------------------------
...
..
..
--------------------------------

Upvotes: 16

Views: 26308

Answers (5)

user5159921
user5159921

Reputation:

With the latest version of Angular Material 5, you should add just a property "mat-sort-header" and it will sort out of the box. Also, you could add some DatePipe so you can format that Date object.

<mat-table>
  <ng-container matColumnDef="fromDate">
    <mat-header-cell *matHeaderCellDef mat-sort-header> 
       <span translate>date</span>
    </mat-header-cell>
    <mat-cell *matCellDef="let row"> 
       {{row.fromDate | date: 'dd MMM., yyyy, HH:mm' }}
    </mat-cell>
  </ng-container>
</mat-table>

I also think Andriy has already helped with this plnkr (plnkr.co/edit/z1BmTxFWAEvWQuMIAXCv?p=preview)

Upvotes: 6

rschouwenaar
rschouwenaar

Reputation: 11

The easiest way to sort on a date in the Material Table is converting your date to a Unix timestamp in the sortingDateAccessor.

this.dataSource.sortingDataAccessor = (item, property) => {
        switch (property) {
            case 'birthday':
                return new Date(item.birthday).getTime()

            default:
                return item[property]
        }
}

Upvotes: 1

Sagar Kharche
Sagar Kharche

Reputation: 2681

Here is solution:

this.dataSource.sortingDataAccessor = (item, property): string | number => {
  switch (property) {
    case 'fromDate': return new Date(item.fromDate).toNumber();
    default: return item[property];
  }
};

MatTableDataSource has sortingDataAccessor which we can customize as per our need.

Upvotes: 29

Jos&#233; Salina
Jos&#233; Salina

Reputation: 148

In addition to the Sagar Kharche's post, if your date is from firebase, I recommended you to do this:

this.dataSource.sortingDataAccessor = (item, property) => {
    console.log(item)
    switch (property) {
      case 'fromDate': {
        return new Date(item.fromDate.seconds * 1000);
      }
      default: return item[property];
    }
  };

Upvotes: 2

Derek J.
Derek J.

Reputation: 1460

Expanding on Sagar Kharche's answer, if you are using the sorting function from the material documentation and using moment.js for your dates, this way will work as well.

sortData(data: Job[]): Job[] {
if (!this.sort.active || this.sort.direction === '') { return data; }

return data.sort((a, b) => {
  let propertyA: number | Date | string = '';
  let propertyB: number | Date | string = '';

  switch (this.jobSort.active) {
    case 'status': [propertyA, propertyB] = [a.status, b.status]; break;
    case 'type': [propertyA, propertyB] = [a.type, b.type]; break;
    case 'time': [propertyA, propertyB] = [new Date(moment(a.time, 'MMM Do LT').toDate()),
    new Date(moment(b.time, 'MMM Do LT').toDate())]; break;
  }

  const valueA = isNaN(+propertyA) ? propertyA : +propertyA;
  const valueB = isNaN(+propertyB) ? propertyB : +propertyB;

  return (valueA < valueB ? -1 : 1) * (this.jobSort.direction === 'asc' ? 1 : -1);
});
}

Upvotes: 1

Related Questions