2

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)">
0

1 Answer 1

3

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!

DEMO


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;
  })
}

DEMO

Sign up to request clarification or add additional context in comments.

7 Comments

Works Perfect! Thank you. I did leave off one detail that you may be able to help with? I have 2 sections. today and current. this filters all of them at once and leaves off my date filtering. Is there anyway to keep my date filtering? I edited above.
Glad to hear it worked. as to your follow-up... I think I understand what you mean. Fast solution is to to first filter the dates and then refilter with the above code I provided. It's ugly tho. But I have a hard time piecing these codes together, since I cannot see the whole picture, just a couple of code snippets and not even sure what exactly is going on in your app.
My apologies. I have edited my code to make it a little more clear.
Not a problem. Thank you for all the help :)!
Cody, I updated answer and transformed code to pipe instead of having the method in the component :) Hopefully that works for you now :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.