Angular Material data table column sort by date range

瘦欲@ 提交于 2020-07-07 08:18:38

问题


How to sort a date column based on the date range? Angular material data table. I am working a project now facing a problem on how to date column sort data based on the date range fromDate and toDate using with filterPredicate or any other option in mat-table.

The date column will be shown in between date range. Please refer screenshot and look at the project in stackblitz here

https://stackblitz.com/edit/angular-pkkvbd-cdtxwz-date-range-filter?embed=1&file=app/table-filtering-example.ts

If I selected 1 Jan 2019 to 31 Dec 2020 the data will be shown all the between date results


回答1:


TL;DR: https://stackblitz.com/edit/angular-pkkvbd-cdtxwz-date-range-filter-jzlwxr?file=app/table-filtering-example.ts

You want to not only sorting but also filtering your table. These are separated concerns in angular material, considering you are using angular material. You will have to provide the filtering components first and use that data to implement a filterPredicate function manually, yes manually.

Filtering:

export class TableFilteringExample {
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  dataSource = new MatTableDataSource(ELEMENT_DATA);

  applyFilter(filterValue: string) {
    this.dataSource.filterPredicate = filterPeriod;
  }

  filterPeriod(data: T, filter: string) {
    return data.referenceDate > startDateFilter.value() && data.referenceDate < endDateFilter.value();
  }
}

Sorting functions are also available for your material.table component, but this component comes out-of-the-box for you. Refer to https://material.angular.io/components/table/overview#sorting on how to use the MatSort component properly:

<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
...

then, in your .ts component, you will refer to the matSort as:

    @ViewChild(MatSort, {static: true}) sort: MatSort;

You need to complete several steps if you want to complete the story and a lettle of reading to understand how to adapt the material components to your case. I suggest you to start your jorney here https://material.angular.io/components/table/overview#sorting




回答2:


In order to achieve your expected result, you need to change the dataSource type. Also you need a method to rebuild your array of items based on the user's date range selection.

Your xxx.component.ts should look like this.

import { Component } from '@angular/core';
import { MatTableDataSource } from '@angular/material';
import { DatePipe } from '@angular/common';
import {FormControl, FormGroup} from '@angular/forms';
import * as moment from 'moment';

export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  DOB: Date;
  created: Date;
}

const ELEMENT_DATA: PeriodicElement[] = [
  { position: 1, name: 'Hydrogen', weight: 1.0079, DOB: new Date(2016, 11, 24), created: new Date(2015, 15, 24) },
  { position: 2, name: 'Helium', weight: 4.0026, DOB: new Date(2018, 18, 24), created: new Date(2018, 11, 24) },
  { position: 3, name: 'Lithium', weight: 6.941, DOB: new Date(1993, 6, 12), created: new Date(1999, 12, 15) },
  { position: 4, name: 'Beryllium', weight: 9.0122, DOB: new Date(2001, 7, 6), created: new Date(2011, 10, 6) },
  { position: 5, name: 'Boron', weight: 10.811, DOB: new Date(2020, 5, 9), created: new Date(2020, 5, 9) },
  { position: 6, name: 'Carbon', weight: 12.0107, DOB: new Date(2008, 7, 14), created: new Date(2008, 7, 14) },
  { position: 7, name: 'Nitrogen', weight: 14.0067, DOB: new Date(1998, 11, 18), created: new Date(1998, 11, 18) },
  { position: 8, name: 'Oxygen', weight: 15.9994, DOB: new Date(2002, 2, 24), created: new Date(2002, 2, 24) },
  { position: 9, name: 'Fluorine', weight: 18.9984, DOB: new Date(2006, 4, 29), created: new Date(2006, 4, 29) },
  { position: 10, name: 'Neon', weight: 20.1797, DOB: new Date(2040, 5, 30), created: new Date(2040, 5, 30) },
];

/**
 * @title Table with filtering
 */
@Component({
  selector: 'table-filtering-example',
  styleUrls: ['table-filtering-example.css'],
  templateUrl: 'table-filtering-example.html',
})
export class TableFilteringExample {
  displayedColumns: string[] = ['position', 'name', 'weight', 'DOB', 'founded'];
  dataSource = ELEMENT_DATA;
  pipe: DatePipe;

filterForm = new FormGroup({
    fromDate: new FormControl(),
    toDate: new FormControl(),
});

get fromDate() { return this.filterForm.get('fromDate'); }
get toDate() { return this.filterForm.get('toDate'); }

  constructor() {
  }

  getDateRange(value) {
    // getting date from calendar
    const fromDate = value.fromDate
    const toDate = value.toDate
    const tempData = <any>this.dataSource;
    let selectedItems: PeriodicElement[] = [];
    if(fromDate !== '' && toDate !== '') {
              tempData.forEach((item, index) => {
            if (item.DOB >= fromDate && item.DOB <= toDate) {
                selectedItems.push(item);
            }
        });

        this.dataSource = selectedItems;
    }
  }


  applyFilter(filterValue: string) {
    // this.dataSource.filter = filterValue.trim().toLowerCase();
  }
}



回答3:


You can use filter function.

getDateRange(value) {
    this.dataSource.data = ELEMENT_DATA;
    const fromDate = value.fromDate
    const toDate = value.toDate
    this.dataSource.data = this.dataSource.data.filter(e=>e.DOB > fromDate && e.DOB < toDate ) ;
  }

The filter() method creates a new array with all elements that pass the test implemented by the provided function.

More information about filter function

Stackblitz example based on your example.



来源:https://stackoverflow.com/questions/55517077/angular-material-data-table-column-sort-by-date-range

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!