Vue based array filtering

Calv :

I have created a demo website to sell products to customers. This website uses filters/search/sort etc to ease navigating through different products. The issue I have is related to filtering and search. I want to make my filters such that they work on the result of search. I have attempted this using checkboxes and the computed properties in Vue.

HTML

<div id="app">
            <h5>Search</h5>
            <input type="text" v-model="search" placeholder="Search title.."/><br><br>
            <h5>Filter</h5>
            <li v-for="filter in possibleFilters" :key="filter">
                <label>
                    <input type="checkbox" @change="toggleFilter(filter)" :checked="filters.includes(filter)">

                <span >{{filter}}</span>
                </label>
            </li>          
            <div class="block" v-for="(product, index) in filteredSearch">
                        <hr>
                        <h3>{{product.name}}</h3>
                        <p>Price: £{{product.price}}</p>
                        <p>Location: {{product.location}}</p>
                        <hr>

</div>
</div>

JavaScript

new Vue({
   el: "#app",
   data: {
      filters: [],
      search: "",
      products: [{
            name: "milk",
            location: "London",
            price: 100
         },
         {
            name: "oranges",
            location: "Birmingham",
            price: 80
         },
         {
            name: "apples",
            location: "Edinburgh",
            price: 90
         },
         {
            name: "bananas",
            location: "Paris",
            price: 120
         },
         {
            name: "bread",
            location: "Paris",
            price: 110
         },
         {
            name: "water",
            location: "Oslo",
            price: 90
         },
         {
            name: "soda",
            location: "London",
            price: 90
         },
         {
            name: "tea",
            location: "Oslo",
            price: 120
         },
         {
            name: "bakedbeans",
            location: "Oslo",
            price: 140
         }
      ],
   },
   methods: {
      toggleFilter(newFilter) {
         this.filters = !this.filters.includes(newFilter) ?
            [...this.filters, newFilter] :
            this.filters.filter(f => f !== newFilter)
      }
   },
   computed: {
      possibleFilters() {
         return [...new Set(this.filteredSearch.map(x => x.location))]
      },

      filteredSearch() {
         return this.products.filter(p => {
            var searchProduct = p.name.toLowerCase().includes(this.search.toLowerCase());
            var filterProduct = this.filters.length == 0 || this.filters.includes(p.location);

            return searchProduct && filterProduct
         })
      }
   },
})

The problem is I cannot select the filter more than once. The filter is based on the location, my goal is to be able to apply the filter more than once. At the moment I can only select one filter at a time.

i.e if I search for "l" it returns milk and apples, the filters shows London and Edinburgh, I can only select either London or Edinburgh but not both. If I select London, it should only show me "Milk" while still showing me the option of 'Edinburgh' and when I select both it should show me both "Milk" and "Apples"

A fiddle showing the problem: https://jsfiddle.net/Calv7/L1vnqh63/9/

Any help will be appreciated. Thanks.

Serg :

Here a quick and dirty solution based on your fiddle. Just to give you an idea how to separate both filters. Try the solution here https://jsfiddle.net/4839spkx/

 possibleFilters() {
    // we have some input, so show all location filters available in the filtered by input products
    if (this.search) {
        const filteredByInput = this.products.filter(p => p.name.includes(this.search.toLowerCase()))
        return [...new Set(filteredByInput.map(p => p.location))]
    }
    return [...new Set(this.filteredSearch.map(x => x.location))]
 },

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=220830&siteId=1