Vesko_dev
Vesko_dev

Reputation: 436

Javascript - How to filter with multiple checkboxes in Vue.js?

Here is my code for the filter, sort, and search together and everything works fine

<template>
  <h5>List of Products</h5>

        <h3>Filter</h3> 
        <button v-on:click="resetOptions">Reset</button>
        <button v-on:click="sorting">Sorting</button>
        <button v-on:click="sorting2">Sorting2</button>
        <select v-model="category">
            <option value="Accessories">Accessories</option>
            <option value="Laptop">Laptop</option>
            <option value="Stationary">Stationary</option>
        </select> 
        <div>
        <input type="checkbox" name="test" id="test" v-model="city" value='Roma' @change="uniqueCheck">
        <label for="test"> Roma</label>
        <input type="checkbox" name="test2" id="test2" v-model.trim="city" value='Barselona' @change="uniqueCheck">
        <label for="test2"> Barselona</label>
        <input type="checkbox" name="test3" id="test3" v-model.trim="city" value='Milano' @change="uniqueCheck">
        <label for="test3"> Milano</label>
        </div>
         <!-- <select v-model="city">
            <option value="Barselona">Barselona</option>
            <option value="Roma"> Roma </option>
            <option value="Milano">Milano</option>
        </select>  -->

        <input type="text" v-model="name" placeholder="Filter By Name"/>

        <label for="vol">Price (between 0 and 1000):</label>
    
        <input type="range" v-model.trim="range" min="0" max="1000" step="10"/>  
        <ul>
            <li v-for="product in filterProducts" :key="product.name"> Product Name : {{product.name}} - Price : {{product.price}} ({{product.category}}) 
                {{product.city}}
            </li>
        </ul>
</template>

<script>
export default {
 data: ()=> ( {

           
            city:[ ],
            category: '',
            name: '',
            range: '10000',
            products: [
                { name: "Keyboard", price: 44, category: 'Accessories', city:'Roma'},
                { name: "Mouse", price: 20, category: 'Accessories', city:'Barselona'},
                { name: "Monitor", price: 399, category: 'Accessories', city:'Roma'},
                { name: "Dell XPS", price: 599, category: 'Laptop', city:'Roma'},
                { name: "MacBook Pro", price: 899, category: 'Laptop', city:'Roma'},
                { name: "Pencil Box", price: 6, category: 'Stationary', city:'Barselona'},
                { name: "Pen", price: 2, category: 'Stationary', city:'Milano'},
                { name: "USB Cable", price: 7, category: 'Accessories', city:'Milano'},
                { name: "Eraser", price: 2, category: 'Stationary', city:'Roma'},
                { name: "Highlighter", price: 5, category: 'Stationary', city:'Roma'}
            ]

        }),

              computed: {
            filterProducts: function(){
                return this.filterProductsByName(this.filterProductsByRange(this.filterProductsByCity(this.filterProductsByCategory(this.products))))
            },

        },
        
        methods: {

            filterProductsByCategory: function(products){
                return products.filter(product => !product.category.indexOf(this.category))
            },

            filterProductsByName: function(products) {
                return products.filter(product => !product.name.toLowerCase().indexOf(this.name.toLowerCase()))
            },

            filterProductsByCity: function(products) {
                return products.filter(product => !product.city.indexOf(this.city))
            },

            filterProductsByRange: function(products){
                return products.filter(product => (product.price >= 0 && product.price <= this.range) ? product : '')
            },

            sorting:function(){
                this.products.sort((a,b)=>(a.price > b.price) ? 1 : -1)
            },
             sorting2:function(){
                this.products.sort((a,b)=>(a.price < b.price) ? 1 : -1)
            },

            uniqueCheck(e){
            this.city = [];
            if (e.target.checked) {
                 this.city.push(e.target.value);
               }
         },

            resetOptions:function(){
                this.category='',
                this.city='',
                this.name='',
                this.range='1000'
            },
        },

}
</script>

<style>

</style>

But I want also to have multiple checkboxes filters, for example, if I checked city 'Barcelona's and 'Roma' I want to show me products with city's Barcelona and Roma. This code will not work because @change function, I tried without that but the result is this when I clicked the second checkbox I got nothing

enter image description here

How I can have that filter also here?

Upvotes: 0

Views: 1229

Answers (1)

Solal Solal
Solal Solal

Reputation: 93

Your filterProductsByCity method is not correct.

It should check wether the product's city is listed in your this.city property.

When you check your checkboxes, it will add their value to the city property :

ex: ['barcelona', 'montreal']

So you could do the following:

filterProductsByCity: function(products) {
    return products.filter(product => this.city.indexOf(product.city) !== -1)
}

Upvotes: 1

Related Questions