Reputation: 61
I have a list of statuses whose values are: Dispatched, open, and closed. When I click on a checkbox I want to filter the results
<ion-item *ngFor="let s of appointmentStatus" >
<ion-checkbox [(ngModel)]="s.checked" (click)="updateFilter(s)"></ion-checkbox>
<ion-label >{{ s.status }}</ion-label>
</ion-item>
<div *ngFor="let a of todaysAppointments>
//list of appointments goes here
I have tried to come up with a way to do this with pipes, but I have not found a good example and I am rather new. Any help would be appreciated.
if ((appDate.getDay() == currentDate.getDay()) && (appDate.getMonth() == currentDate.getMonth()) && (appDate.getFullYear() == currentDate.getFullYear()) && this.appointments[i].status != 'Pending') {
this.todaysAppointments.push(this.appointments[i]);
}
if ((appDate.getDay() < currentDate.getDay()) && (appDate.getMonth() >= currentDate.getMonth()) && (appDate.getFullYear() >= currentDate.getFullYear()) && this.appointments[i].status != 'Pending') {
this.upcomingAppointments.push(this.appointments[i]);
}
So what you did below works perfect when you only have a single array. On my html I have it divided up into Todays and upcoming appointments. So I first have the page load and show all the appointments in there corresponding sections. Then on top of that I want to filter by the checkboxes.
<h2 style="background-color:#387ef5">Today's Appointments</h2>
<div *ngFor="let a of todaysAppointments | filter: searchTerm" (click)="openPage(a)">
<h2 style="background-color:#387ef5">Upcoming Appointments</h2>
<div *ngFor="let a of upcomingAppointments | filter: searchTerm" (click)="openPage(a)">
Upvotes: 2
Views: 2518
Reputation: 73357
EDIT:
Since we are dealing with two arrays, here is the original answer transformed to a pipe instead of just having the filter method in the component file.
We can also keep the updateFilter(s)
method if you want to there add or remove filter values, or you can do it in template for the click event:
(click)="s.checked ?
filterArr.push(s.status) : filterArr.splice(filterArr.indexOf(s.status), 1)
I personally like having that logic in the component to keep the template clean, but that is totally up to you :)
And in the template we pass that array to the pipe:
<div *ngFor="let a of todaysAppointments | filterPipe: filterArr">
The pipe would look like this, where values
is the array you want to filter, and args
is the array with the checkboxes checked. (You'd want to reconsider the naming). We have to make the pipe impure so that it will be fired whenever changes happen.
@Pipe({name: 'filterPipe', pure: false})
export class MyPipe implements PipeTransform {
transform(values: any, args?: any[]): any[] {
return values = values.filter(a => {
return args.length ? args.indexOf(a.status) != -1 : values;
})
}
}
That should do it!
ORIGINAL ANSWER:
Maybe a custom pipe is not necessary here at all. You can just use the Array.prototype.filter()
on your click event.
Also we need to check if the checkbox is checked or not, and filter based on the values that are checked. I have here inserted them in a separate array, filterArr
.
So in updateFilter(s)
method we do that check first, push that filter value to the array, or remove it. Then filter by the values, or return all appointments if filterArr
is empty:
We have a separate array that stores all appointments called allAppointments
, from which we filter the values to todasyAppointments
.
updateFilter(appt) {
if(appt.checked) {
// checkbox is checked, push to filterArr
this.filterArr.push(appt.status)
}
else {
// unchecked box, let's remove it from array
let index = this.filterArr.indexOf(appt.status)
this.filterArr.splice(index, 1)
}
// filter by the values set in filterArr, or if empty, return all appointments
this.todaysAppointments = this.allAppointments.filter(a => {
return this.filterArr.length ?
this.filterArr.indexOf(a.status) != -1 : this.allAppointments;
})
}
Upvotes: 3