ARNON
ARNON

Reputation: 1217

How to make multiple search filters work with a for loop in Vue Bootstrap?

I have a table with some filters in each column but when I type anything all the items disappear. The console does not return any error.

Here’s the code:

<template>
  <div>
    <b-table
      id="the-table"
      :per-page="perPage"
      :current-page="currentPage"
      :items="filteredItems"
      :fields="fields"
    >
      <template slot="top-row" slot-scope="{ fields }">
        <td v-for="field in fields" :key="field.key">
          <input v-model="filters[field.key]" :placeholder="field.label" />
        </td>
      </template>
    </b-table>
    <b-pagination v-model="currentPage" :total-rows="rows" :per-page="perPage" aria-controls="the-table"></b-pagination>
  </div>
</template>
<script>
import axios from "axios";

export default {
  data() {
    return {
      filters: {
        option: "",
        style: "",
        stock: "",
      },
      items: [],
      fields: [
        { key: "options", label: "Options", sortable: true },
        { key: "style", label: "Style", sortable: true },
        { key: "stock", label: "Stock", sortable: true },
        { key: "type", label: "Type", sortable: true },
        { key: "class", label: "Class.", sortable: true },
      ],
      perPage: 15,
      currentPage: 1,
    };
  },
  created() {
    this.getTable();
  },
  methods: {
    getTable() {
      axios
        .get("./data/options.json")
        .then((res) => (this.items = res.data))
        .catch((error) => console.log(error));
    },
  },
  computed: {
    rows() {
      return this.items.length;
    },
    filteredItems() {
      return this.items.filter((d) => {
        return Object.keys(this.filters).every((f) => {
          return this.filters[f].length < 1 || this.filters[f].includes(d[f]);
        });
      });
    },
  },
};
</script>

I am trying to filter an array of objects like this:

[{"option": "ABEVH160", "style": "American", "stock": "ABEV3", "type": "CALL", "class": "ITM"},
{"option": "BBAS230", "style": "European", "stock": "BBAS3", "type": "PUT", "class": "ATM"},
{"option": "BBDC180", "style": "American", "stock": "BBDC4", "type": "CALL", "class": "OTM"}]

My goal is to be able to filter each of the columns individually: data-table

Does anyone know what I’m missing?

Upvotes: 2

Views: 576

Answers (2)

Igor Moraru
Igor Moraru

Reputation: 7729

The problem is with the condition:

return this.filters[f].length < 1 || this.filters[f].includes(d[f]);

d[f] is the full value and this.filters[f] is the search string. Obviously this does not work since it checks if the full word is contained in a substring. Simply invert the condition:

return this.filters[f].length < 1 || d[f].includes(this.filters[f]);

You can see it working here.

Upvotes: 3

StevenSiebert
StevenSiebert

Reputation: 1426

What you want seems to be something like DataTable Filter | Filter Row in PrimeVue. I tried to find something similar in the documentation of bootstrap-vue (documentation), but couldn´t find anything like that.

Maybe you are in a stage where you can still implement PrimeVue in your project. I´m using Filter Row from PrimeVue by myself and can recommend it.

Upvotes: 2

Related Questions