0

I'm trying to create some dynamic filters in bootstrap-vue 2.0.0-rc.11 for the bootstrap-table columns

In my example I did this

<b-table class="io-store-list-table table-striped" show-empty hover stacked="md" :items="stores" :fields="storeFields" :current-page="currentPage" :per-page="perPage" :filter="filter" :sort-by.sync="sortBy" :sort-desc.sync="sortDesc" :sort-direction="sortDirection" @filtered="onFiltered" empty-filtered-text="{l s='There are no records matching your request' mod='ioweb_slocator'}">

                    <template slot="top-row" slot-scope="data">
                        <th v-for="field in fields">
                            <input v-if="field.filterable" type="text" @click.stop value="" />
                        </th>

                    </template>
                    <template v-for='field in formatted' :slot='field' slot-scope='row'>
                        <span v-html='row.value'></span>
                    </template>
                </b-table>
                <b-row>
                    <b-container>
                        <b-col xs="12" class="my-1 io-pagination">
                            <b-pagination :total-rows="totalRows" :per-page="perPage" v-model="currentPage" class="my-0"/>
                        </b-col>
                    </b-container>
                </b-row>
  </b-table>

Which renders a table like this

enter image description here

Now I'm attempting to filter the items based on what value is entered in each column. For example if I type mypartnername at the input box below Partner column, I would like to dynamically filter the items based on the row key called partner but I'm not sure how to approach this.

Based on the accepted answer I was able to create a structure that helped me like this.

Step 1:

Create a property filteredResults and set it equal to my unfiltered items property

let app = new Vue({
    el: "#app",
    data() {
        return {
            ...            
            stores: stores,
            groups: groups,
            totalRows: stores.length,
            filters: [],
            loop: 0,
            filteredResults: stores,
        }
    },

Step 2

Used filteredResults in the :items slot

Step 3

Create a single function to set the filters

    methods: {
       ...
        setFilter(property, value) {
            console.log("Filtering");
            this.filters[property] = {};
            this.filters[property].value = value;
            this.filteredResults = this.stores.filter(item => {
                let keep = true;
                // This is a basic equality filter. What I did in the actual code was to have an object with filter functions for each key. If a key was missing, it defaulted to straight equality.
                this.fieldKeys.forEach(key => {
                    keep =
                        keep &&
                        (this.filters[key] === undefined || this.filters[key].value === undefined || this.filters[key].value === "" || item[key].match(this.filters[key].value));
                });
                return keep;
            });
        },

    },
gabtzi
  • 573
  • 3
  • 8
  • 24

1 Answers1

2

what about something like this? I dont know if i got your problem right.

<input v-if="field.filterable" @onchange="setFilter(field.property, $event.target.value)" type="text" @click.stop />

in the setFilter function you could do something like this:

setFilter(property, value) {
    this.filters[property].value = value
}

get your results with a computed property

filteredResults(){
   return users = this.users.filter((item) => {
      for (var key in this.filters) {
        if (item[key].value === undefined || item[key].value != filter[key])
          return false;
      }
      return true;
    }
}

I dont know if it works, couldnt test it. I am curious about the solution here.

Noah Porfido
  • 126
  • 4
  • I will definitely try it and let you know :) – gabtzi Mar 11 '20 at 16:15
  • Your answer was really helpful to find a working way so I could proceed but it didn't work immediately in my case. Let me note the issues that I faced. 1. The computed property wouldn't automatically force a repaint of the bootstrap table when filtering even when setting the `filteredResults` variable in the `:items` slot of the table. 2. The function to compare the keys didn't quite work because item[key] was undefined and throwing an error when parsing the value. I wrote one to suit my case though so all's good there :) I'll accept it because it really really helped – gabtzi Mar 11 '20 at 18:10
  • Nice feedback, glad you got it. – Noah Porfido Mar 11 '20 at 18:31