lundi 25 décembre 2017

Filter results based on checkboxes in Angular

I want to have a filter based on active-states from available checkboxes.

First everything should gets displayed, after a filter is selected, in this case an ability, it should only display objects which contains atleast the ability.

My intitial thought process was like that: Create an array which consists of all results and also have an array which consists of the filtered results. Then after a checkbox gets unchecked just show the complete array again. However that doesn't work because sometimes if the complete array is shown again it shows too much results because some checkboxes are still active.

Stackblitz: http://ift.tt/2DbmSEB

App Component:

import { Component, OnInit } from '@angular/core';

interface Hero {
  name: string;
  powers: string[];
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {

  fullHeroes: Hero[] = [];
  heroes: Hero[] = [];
  powers = new Set<String>();

  constructor() {
    this.heroes.push(
      {
        name: 'Goku',
        powers: ['Strength', 'Speed', 'Teleportation', 'Plot-Armor']
      },
      {
        name: 'Vegeta',
        powers: ['Strength', 'Speed', 'Teleportation']
      },
      {
        name: 'Mr.Satan',
        powers: ['Coolness']
      },
      {
        name: 'A Nobody',
        powers: []
      }
    );

    this.heroes.forEach(h => {
      h.powers.forEach(power => this.powers.add(power));
    });

    this.fullHeroes = this.heroes.slice(0);

  }


  filter(type, name, checked) {
    console.log(type); // type of filter (here power)
    console.log(name); // name of the power
    console.log(checked);

    switch (type) {
      case 'power': {
        if (checked) {
          const returnArray = [];
          for (let i = 0; i < this.heroes.length; i++) {
            const currentHero = this.heroes[i];
            if (currentHero) {
              for (let j = 0; j < currentHero.powers.length; j++) {
                if (currentHero.powers[j] === name) {
                  returnArray.push(currentHero);
                }
              }
            }
          }
          this.heroes = returnArray;
          console.log('this.fullHeroes');
          console.log(this.fullHeroes);
        } else {
          this.heroes = JSON.parse(JSON.stringify(this.fullHeroes));
          // here another loop to check which values should still be removed!
        }
        return;
      }
    }
  }

}

App.Component.html

<div class="container">
  <h1>World of Heroes</h1>
  <p>Filter your Heroes based on some criteria!</p>

  <div class="filter">
    <form #heroForm="ngForm">

      <fieldset>
        <legend>Choose the powers</legend>
        <div class="form-check" *ngFor="let power of powers">
          <label class="form-check-label">
              <input  class="form-check-input" 
              type="checkbox" 
              [name]="power" 
              (change)="filter('power', $event.target.name, $event.target.checked)"> 
            </label>
        </div>

      </fieldset>
    </form>
  </div>

  <hr>
<h2>Results:</h2>

  <div class="row result-list">

    <div class="col-md-4 hero" *ngFor="let hero of heroes">
      <h3>Name: </h3>
      Powers:
      <ul>
        <li *ngFor="let power of hero.powers"></li>
      </ul>
    </div>

  </div>

</div>




Aucun commentaire:

Enregistrer un commentaire