Norbertho
Norbertho

Reputation: 47

How to filter an array in Vue.js with multiple select buttons?

I try to filter an object of array in Vue.js. have products collection in this vue component. I would like to filter this collection with select buttons. These products are food products and as default I would like to show all products but if I select the lactosefree button the I would like to show only products are lactosefree. In my database these options true or false. so for example if I have a cheese that lactose free then in the database I have a field lactosefree with value true.

I have tried to filter the array with computed property but I don't really know how to do it.

<div class="col-12 justify-content-between row filterbtn">
    <label class="btn btn-primary">
        <input v-model="selected" value="gluteinfree" type="checkbox"  class="check2">GLUTEIN FREE
    </label>

    <label class="btn btn-primary">
        <input v-model="selected" value="lactosefree" type="checkbox"  class="check2">LAKTOZ FREE
    </label>
</div>
<script>
    export default{
        data(){
            return{
                products: [ 
                    { "id": 1, "productName": "Majomkenyérfa kivonat", "gluteinfree": true,  "lactosefree": false, }, 
                    { "id": 2, "productName": "Kókuszolaj", "gluteinfree": false, "lactosefree": true,}, 
                    { "id": 3, "productName": "C-vitamin 80mg", "gluteinfree": true, "lactosefree": true, }, 
                ],
                selected: [],
            }   
        },

        computed: {
            //
        },
    }
</script>

As default I would like to show all the products. but when i click the gluteinfree select button I would like to show only the First and the last products where the gluteinfree is true.

Upvotes: 0

Views: 3320

Answers (1)

Daniel
Daniel

Reputation: 35724

Here is the code you can use for your computed. This will loop over all the products and compare each against a list of selected options

return this.products.filter(product => this.selected.every(selection => product[selection] === true));

note that it's using filter and every which for old browsers may require polyfills. You can can also convert to a more verbose for loop though.

Code:

new Vue({
  el: '#app',
  data() {
    return {
      products: [{
          "id": 1,
          "productName": "Majomkenyérfa kivonat",
          "gluteinfree": true,
          "lactosefree": false,
        },
        {
          "id": 2,
          "productName": "Kókuszolaj",
          "gluteinfree": false,
          "lactosefree": true,
        },
        {
          "id": 3,
          "productName": "C-vitamin 80mg",
          "gluteinfree": true,
          "lactosefree": true,
        },
      ],
      selected: [],
    }
  },
  computed: {
    zsir() {
      return this.products.filter(prod => this.selected.every(sel => prod[sel] === true));
    },
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div class="col-12 justify-content-between row filterbtn">
    <label class="btn btn-primary">
  <input v-model="selected" value="gluteinfree" type="checkbox"  class="check2">GLUTEIN FREE</label>
    <label class="btn btn-primary"><input v-model="selected" value="lactosefree" type="checkbox"  class="check2">LAKTOZ FREE</label>
  </div>
  <ul>
    <li v-for="prod in zsir" :key="prod.id">{{prod.productName}}</li>
  </ul>
</div>

Upvotes: 4

Related Questions