Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a dropdown filter for JSON data in Vue

I want to use a dropdown that filters through my JSON data and displays different JSON data items if they match the dropdown option. So far I've managed to get it so a function runs when someone selects an item from the dropdown menu, but i'm unsure why the filter doesn't work, as i'm not getting any errors in the console or in WebStorm.

Here's an example of my code and JSON data:

<template>
    <b-container id="product-list">
        <b-row>
            <b-col>
                <div>
                    <b-dropdown id="ddown4" text="Product Type" class="m-md-2">
                        <b-dropdown-item @click="FilterProducts" v-model="selectedCategory">4.5</b-dropdown-item>
                        <b-dropdown-item @click="FilterProducts" v-model="selectedCategory">10.5</b-dropdown-item>
                    </b-dropdown>
                </div>
            </b-col>
        </b-row>
        <hr>
        <b-row>
            <b-col md="4" v-for="product in Products">
                <img class="img-fluid" :src="product.image"/>
                <h5>{{ product.product_name }}  </h5>
                <p class="original-price strikethrough">£{{ product.original_price }}</p>
                <p>£{{ product.final_price }}</p>
            </b-col>
        </b-row>
    </b-container>
</template>
<script>
    import Axios from "axios";

    export default {
        name: 'Products',
        data() {
            return {
                Products: null,
                selectedCategory: ''
            }
        },
        mounted() {
            Axios.get('/products.json')
                .then(response => (this.Products = response.data.data))
        },
        methods: {
            FilterProducts() {
                var vm = this;
                var category = vm.selectedCategory;

                if(category === '') {
                    return vm.Products;
                } else {
                    return vm.Products.filter(function(product) {
                        return product.attributes.tog === category;
                    });
                }
            }
        }
    }
</script>

JSON data example:

"data": [
    {
      "id": "83",
      "product_name": "TV",
      "category": "Clearance",
      "original_price": "139.0000",
      "final_price": "105.0000",
      "attributes": {
        "size": "260x220",
        "tog": "10.5 tog"
      }
      "url": "/tv"
    }
like image 601
user2953989 Avatar asked Nov 14 '18 18:11

user2953989


1 Answers

Your computed method is reactive to selectedCategory and no need to call @click as your are using v-model.

<template>
    <b-container id="product-list">
        <b-row>
            <b-col>
                <div>
                    <b-dropdown id="ddown4" text="Product Type" class="m-md-2">
                        <b-dropdown-item v-model="selectedCategory">4.5</b-dropdown-item>
                    </b-dropdown>
                </div>
            </b-col>
        </b-row>
        <hr>
        <b-row>
            <b-col md="4" v-for="product in filteredProducts">
                <img class="img-fluid" :src="product.image"/>
                <h5>{{ product.product_name }}  </h5>
                <p class="original-price strikethrough">£{{ product.original_price }}</p>
                <p>£{{ product.final_price }}</p>
            </b-col>
        </b-row>
    </b-container>
</template>
<script>
    import Axios from "axios";

    export default {
        name: 'Products',
        data() {
            return {
                Products: null,
                selectedCategory: ''
            }
        },
        mounted() {
            Axios.get('/products.json')
                .then(response => (this.Products = response.data.data))
        },
        computed: {
            filteredProducts() {

                if(this.selectedCategory === '') {
                    return this.Products;
                } else {
                    const category = this.selectedCategory;
                    return this.Products
                               .filter((product) => product.attributes.tog === category)
                }
            }
        }
    }
</script>
like image 196
calmar Avatar answered Oct 15 '22 07:10

calmar