user5582406
user5582406

Reputation:

Angular 6 Checkbox Filter

I want to filter a list of JSON objects (Products) by the variable 'category' using a checkbox.

a porduct is a followed :

  {
  'bikeId': 6,
  'bikeName': 'Kids blue bike',
  'bikeCode': 'KB-3075',
  'releaseDate': 'June 28, 2016',
  'description': 'Kids blue bike with stabalizers',
  'category': 'kids',
  'price': 290.00,
  'starRating': 4.8,
  'imageUrl': 'https://openclipart.org/image/2400px/svg_to_png/1772/bike-kid.png'
}

My current ngFor Loop is as followed:

   <tr *ngFor="let product of products">
                       <td><img *ngIf='showImage' 
                         [src]='product.imageUrl' 
                        [title]='product.bikeName'
                        [style.width.px]='imageWidth'></td>
                       <td>{{product.bikeName}}</td>
                       <td>{{product.bikeCode}}</td>
                       <td>{{product.releaseDate}}</td>
                           <td>{{product.price}}</td>
                           <td>{{product.starRating}}</td>
</tr>

And My current Check boxes are as followed:

 <input type="checkbox" name="All" value="true" /> Mens 
                <input type="checkbox" name="All" value="true" /> Womens 
                <input type="checkbox" name="All" value="true" /> Kids 

I ask this question because i have been searching forums all day to no avail. Some answers do answer it but when i test the code it's either outdated or just doesn't work. Any help would be appreciated.

Upvotes: 7

Views: 11577

Answers (1)

Daniel Gimenez
Daniel Gimenez

Reputation: 20524

Quite surprised you couldn't find an example online, as there are many ways to handle this problem and my answer is just one.

In this example I keep the source of products untouched, but create a second array with that will contain the products displayed. I bind each checkbox to a property of a filter model and when a change occurs I call filterChange() to update my filtered products array from that model.

You don't necessarily need NgModel and two binding and you could certainly dynamically generate the filters from an array which would probably be a good idea as your application grows. You could also use Observables, or create a Pipe to filter the array in NgFor. Really the possibilities are endless.

MyComponent.ts

export class MyComponent {
  filter = { mens: true, womens: true, kids: true };
  products: Product[] = []
  filteredProducts = Product[] = [];

  filterChange() {
    this.filteredProducts = this.products.filter(x => 
       (x.category === 'kids' && this.filter.kids)
       || (x.category === 'mens' && this.filter.mens)
       || (x.category === 'womens' && this.filter.womens)
    );
  }
}

MyComponent.html

<tr *ngFor="let product of filteredProducts"> <!-- ... --> </tr>
<!-- ... --->
<input type="checkbox" [(ngModel)]="filter.mens" (ngModelChange)="filterChange()" /> Mens 
<input type="checkbox" [(ngModel)]="filter.womens" (ngModelChange)="filterChange()" /> Womens 
<input type="checkbox" [(ngModel)]="filter.kids" (ngModelChange)="filterChange()" /> Kids

Upvotes: 5

Related Questions