lundi 14 juin 2021

Vue.js multiple checkbox filter with searchbar filtering and table sorting

I have a vue.js table of pokemons in which I can already search by pokemon's name and generation. And also I can sort the table columns asc/desc if I click in any of them.

I want to introduce multiple checkboxes to this program where I can filter out the table by pokemon types. This checkbox filter should work together with the search filtering, so if I search pokemon generation "IV" with the search field I want to further filter those hits with the checkboxes.

I figured I could not use computed instead I always transfigure my array (pokemonList) to my needs and keep a copy of the original array in a different data variable (originalData). But I don't know how should I implement in this setting the checkbox filtering (checkboxChange method).

This is my template:

<f7-searchbar
    placeholder="Name and generation search"
    :clear-button="true"
    :disable-button="true"
    disable-button-text=""
    v-model:value="searchTerm"
></f7-searchbar>
<div class="filters">
    <f7-checkbox @change="checkboxChange" value="fire"><span>Fire types</span></f7-checkbox>
    <f7-checkbox @change="checkboxChange" value="water"><span>Water types</span></f7-checkbox>
    <f7-checkbox @change="checkboxChange" value="ground"><span>Ground types</span></f7-checkbox>
    <f7-checkbox @change="checkboxChange" value="poison"><span>Poison types</span></f7-checkbox>
</div>


<div class="pokemon-table">
    <table>
    <thead>
        <tr>
        <th @click="sort('name')"><span :class="getSortingDirection('name')"></span>Name</th>
        <th @click="sort('generation')"><span :class="getSortingDirection('generation')"></span>Generation</th>
        <th @click="sort('power')"><span :class="getSortingDirection('power')"></span>Power</th>
        </tr>
    </thead>
    <tbody>
        <tr v-for="pokemon in pokemons" :key="pokemon.id" @click="selectRow(pokemon.id)" :class="{'highlight': (pokemon.id == selectedRow)}">
        <td></td>
        <td></td>
        <td></td>
        </tr>
    </tbody>
    </table>
</div>

And this is my script tag in which

export default {
  data() {
    return {
      originalData: [],
      pokemonList: [],
      searchTerm: '',
      sortBy: '',
      sortOrder: 1,
      selectedRow: null,
    }
  },

  beforeMount() {
    const self = this;
    ajax.methodCall('/Pokemon/Pokemonlist')
    .then(result => self.pokemonList = result.pokemonList)
    .finally(() => self.originalData = self.pokemonList);
  },


  methods: {
    getFilteredList() {
      const self = this;
      let searchData = self.originalData;
      if (self.searchTerm == '') {
        self.pokemonList= self.originalData;
      } else {
        self.pokemonList = searchData.filter(pokemon => {
          const name = pokemon.name.toLowerCase();
          const generation = pokemon.generation.toLowerCase();
          const searchTerm = self.searchTerm.toLowerCase();

          return name.includes(searchTerm) || generation.includes(searchTerm)
        })
      }
    },

    sort(sortBy) {
      const self = this;
      if (self.sortBy == sortBy) {
        self.sortOrder = -self.sortOrder;
      } else {
        self.sortBy = sortBy;
      }

      self.pokemonList= self.pokemonList
        .sort((a,b) => {
          if (a[self.sortBy] >= b[self.sortBy]) {
            return self.sortOrder
          }
        return -self.sortOrder
      })

    },

    getSortingDirection(sortBy) {
      if(sortBy == this.sortBy) {
        return this.sortOrder == 1 ? 'asc' : 'desc';
      }
    },

    selectRow(id) {
      this.selectedRow != id ? this.selectedRow = id : this.selectedRow = null;
    },

    checkboxChange(e) {}
  },

  watch: {
    searchTerm() {
        this.getFilteredList();
    }
  }
}

The data structure of an pokemon in pokemonList is like this:

pokemonList: [
  {
    id: 0,
    name: 'Charizard',
    generation: 'I',
    power: 244,
    type: 'fire',
  },
]



Aucun commentaire:

Enregistrer un commentaire