Search code examples
angulartypescriptfilterangular-pipe

Can't filter using checkboxes in angular 2+


I have a project that displays a list of participants. What I would like to do is filter them by providers using checkboxes in real-time.

The participants:

[
    { 'name': 'test1', 'provider' : {'name': 'provider1'}}
    { 'name': 'test2', 'provider' : {'name': 'provider2'}}
    { 'name': 'test3', 'provider' : {'name': 'provider3'}}
    { 'name': 'test4', 'provider' : {'name': 'provider1'}'}
 ..
]

My html template is:

Here is the list of checkboxes that displays providers. I use this to filter participants.

<div class="form-group" *ngFor="let provider of providers">
    <input type="checkbox" name="providers" value="{{ provider.name }}" [(ngModel)]="provider.checked"
    (change)="displayParticipantsByProvider($event.target.value)">{{ provider.lastName }}
</div>

And here is how I display the participants:

<ul>
    <li *ngFor="let p of participants">{{ p.name }} - {{ p.provider.name }} </li>
</ul>

And my filter function in the component is:

displayParticipantsByProvider(filterVal: any) {
    if (filterVal === '0') {
      this.participants = this.cathechParticipants;
    } else {
      this.participants = this.participants.filter((item) => item.provider.includes(filterVal));
    }
}

This filter returns only whichever checked item is. For instance, if provider 1 is selected from the checkbox, it returns participants where I have provider1 in it. If I select provider2 from the checkbox, it returns only participants with the provider2 in it. My goal is to load both of them since they both are selected. So, how can I load participants using multiple checkboxes which allows me to filter?


Solution

  • Keep track of selected items and match it against providers list, and add it to the participants array.

    The following example is done with Angular Material.

    export class AppComponent {
      selectedProviders: any[];
      providers: any[];
      participants: any[];
    
      providerChange() {
        this.participants = [];
        for (const sp of this.selectedProviders) {
          for (const p of this.providers) {
            if (sp.provider.name === p.provider.name) {
              this.participants.push(p);
            }
          }
        }
      }
    
      ngOnInit() {
        this.providers = [
          { 'name': 'test1', 'provider': { 'name': 'provider1' } },
          { 'name': 'test2', 'provider': { 'name': 'provider2' } },
          { 'name': 'test3', 'provider': { 'name': 'provider3' } },
          { 'name': 'test4', 'provider': { 'name': 'provider1' } }
        ]
      }
    }
    

    HTML:

    <mat-list-item class="primary-imenu-item" role="listitem">
        <mat-form-field class="select-form">
            <mat-select 
            placeholder="Providers" 
            name="providers" 
            class="filter-select" 
            [(ngModel)]="selectedProviders"
            (change)="providerChange()"
            multiple>
              <mat-option *ngFor="let p of providers" [value]="p">
                {{p.provider.name}}
              </mat-option>
            </mat-select>
        </mat-form-field>
      </mat-list-item>
    
      <ul>
        <li *ngFor="let p of participants">{{p.name}}</li>
      </ul>
    

    StackBlitz