Reputation: 43
I'm trying to filter a Material table base on 2 input fields from a Material date picker. The table datasource is coming from an injected service on the table.component.ts
constructor. But I can't make it work.
table.component.html
code:
<div>
<form [formGroup]="form" (submit)="applyDateFilter()">
<mat-form-field>
<input
matInput
placeholder="Date From"
[matDatepicker]="picker1"
formControlName="fromDate"
required
(click)="picker1.open()"
>
<mat-datepicker-toggle
matSuffix [for]="picker1"
></mat-datepicker-toggle>
<mat-datepicker
#picker1></mat-datepicker>
</mat-form-field>
<mat-form-field>
<input
matInput
placeholder="toDate"
[matDatepicker]="picker2"
formControlName="toDate"
required
(click)="picker2.open()"
>
<mat-datepicker-toggle
matSuffix [for]="picker2"
></mat-datepicker-toggle>
<mat-datepicker
#picker2></mat-datepicker>
</mat-form-field>
<button
class="button-form"
mat-raised-button color="accent"
(click)="applyDateFilter()"
[disabled]="form.invalid">Submit</button>
<button mat-raised-button color="accent" type="button" [disabled]="form.invalid">Clear</button>
</form>
<mat-form-field>
<input matInput type="text" #filter (keyup)="doFilter(filter.value)" placeholder="Filter">
</mat-form-field>
</div>
<mat-table
[dataSource]="dataSource" matSort
matSortActive="date"
matSortDirection="desc"
>
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header>Id</mat-header-cell>
<mat-cell *matCellDef="let element">{{element.id }}</mat-cell>
</ng-container>
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header>Name</mat-header-cell>
<mat-cell *matCellDef="let element">{{element.name }}</mat-cell>
</ng-container>
<ng-container matColumnDef="description" >
<mat-header-cell *matHeaderCellDef mat-sort-header>Description</mat-header-cell>
<mat-cell *matCellDef="let element">{{element.description }}</mat-cell>
</ng-container>
<ng-container matColumnDef="email" >
<mat-header-cell *matHeaderCellDef mat-sort-header>Email</mat-header-cell>
<mat-cell *matCellDef="let element">{{ element.email }}</mat-cell>
</ng-container>
<ng-container matColumnDef="phone" >
<mat-header-cell *matHeaderCellDef mat-sort-header>Phone</mat-header-cell>
<mat-cell *matCellDef="let element">{{ element.phone }}</mat-cell>
</ng-container>
<ng-container matColumnDef="date">
<mat-header-cell *matHeaderCellDef mat-sort-header matSortStart="desc">Date</mat-header-cell>
<mat-cell *matCellDef="let element">{{element.date | date: 'dd/MM/yyyy'}}</mat-cell>
</ng-container>
<ng-container matColumnDef="status" >
<mat-header-cell *matHeaderCellDef mat-sort-header>Status</mat-header-cell>
<mat-cell *matCellDef="let element">{{element.status }}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
table.component.ts
code:
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { Company } from '../model/company.model';
import { TableService } from '../service/table.service';
@Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit, AfterViewInit {
displayedColumns = [
'id',
'name',
'description',
'email',
'phone',
'date',
'status'
];
form = new FormGroup({
fromDate: new FormControl(null, { validators: [Validators.required]}),
toDate: new FormControl(null, { validators: [Validators.required]})
});
dataSource = new MatTableDataSource<Company>();
@ViewChild(MatSort) sort: MatSort;
constructor(private tableService: TableService) { }
ngOnInit(): void {
this.dataSource.data = this.tableService.getCompanies();
}
ngAfterViewInit() {
this.dataSource.sort = this.sort;
}
applyDateFilter() {
console.log(this.form);
if (this.form.invalid) {
return
}
//this.dataSource.data = this.dataSource.data.filter(e=>e.date >= this.fromDate && e.date <= this.toDate);
}
doFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
}
}
table.service.ts
code:
import { Subject } from "rxjs";
import { Company } from "../model/company.model";
export class TableService {
companyChanged = new Subject<Company>();
private companies: Company[] = [
{id: '1', name: 'Company1', description: 'test1 test1', email: '[email protected]', phone: '9999-99-9', date: new Date(2020, 1, 16), status: 'active'},
{id: '2', name: 'Company2', description: 'test2 test1', email: '[email protected]', phone: '9999-99-9', date: new Date(2020, 1, 21), status: 'active'},
{id: '3', name: 'Company3', description: 'test3 test1', email: '[email protected]', phone: '9999-99-9', date: new Date(2020, 1, 22), status: 'active'},
{id: '4', name: 'Company4', description: 'test4 test1', email: '[email protected]', phone: '9999-99-9', date: new Date(2020, 1, 23), status: 'inactive'}
];
getCompanies() {
return this.companies.slice();
}
}
company.model.ts
code:
export interface Company {
id: string;
name: string;
description: string;
email: string;
phone: string;
date?: Date;
status: 'active' | 'inactive' | null
}
This is the link of the project on GitHub: https://github.com/christianlacuesta/angular-material-table-date-range-filter
Upvotes: 1
Views: 12830
Reputation: 605
Re-assign your dataArray to dataSource.data on every call of applyFilter() method and compare milliseconds.
applyDateFilter() {
if(this.dateRange.value.start && this.dateRange.value.end){
this.dataSource.data = this.arrayList;
console.log("data",this.dataSource.data);
this.dataSource.data = this.dataSource.data.filter(e=> new Date(e.timestamp).getTime() >= this.dateRange.value.start?.getTime()! && new Date(e.timestamp).getTime() <= this.dateRange.value.end?.getTime()!);
console.log("filterd",this.dataSource.data);
}
}
Upvotes: 0
Reputation: 43
my friend helped me.
added this code to applyDateFilter() method.
applyDateFilter() {
console.log(this.form);
this.dataSource.data = this.tableService.getCompanies();
this.dataSource.data = this.dataSource.data.filter(e=> e.date >= this.form.value.fromDate && e.date <= this.form.value.toDate);
}
and updated the dates on the table.service.ts
private companies: Company[] = [
{id: '1', name: 'Company1', description: 'test1 test1', email: '[email protected]', phone: '9999-99-9', date: new Date('01/16/2021'), status: 'active'},
{id: '2', name: 'Company2', description: 'test2 test1', email: '[email protected]', phone: '9999-99-9', date: new Date('01/21/2021'), status: 'active'},
{id: '3', name: 'Company3', description: 'test3 test1', email: '[email protected]', phone: '9999-99-9', date: new Date('01/22/2021'), status: 'active'},
{id: '4', name: 'Company4', description: 'test4 test1', email: '[email protected]', phone: '9999-99-9', date: new Date('01/23/2021'), status: 'inactive'}
];
Upvotes: 2