Search code examples
vue.jsfiltervuejs3filteringcategories

VueJS 3 Create product filter dependent on each other


I am trying to create a product filters that are dependent on each other like in e-commerce websites. Let's say I have selected X on the first option then the second filter should display only the products of X. The same goes for the reverse way.

Here is my progress so far sandbox link and indented code are below

<script>
export default {
  data() {
    return {
      myObject: {
        Tshirts: ["X", "Y", "Z"],
        Pants: ["A", "B", "C"],
        Coats: ["D", "E"],
      },
      selectedCategoryProducts: "",
      selectedCategorysSub: "",
    }
  },

  computed: {
    subForSelectedProducts() {
      // if selectedCategoryLocation is equal to the first
      var vm = this;
      var products = vm.selectedCategoryProducts;

      if (products === "All") {
        return vm.selectedCategorySub;
      } else {
        return vm.selectedCategorySub.filter(function (selectedCategorySub) {
          return myObject.key === products;
        });
      }
    },

    productsForSelectedSub() {
      var vm = this;
      var sub = vm.selectedCategorySub;
      if (sub === "All") {
        return vm.selectedCategoryProducts;
      } else {
        return vm.selectedCategoryProducts.filter(function (selectedCategoryProducts) {
          return myObject.name === sub;
        });
      }
    },
  },
}
</script>

<template>
  <select v-model="selectedCategoryProducts">
    <option v-for="(value, key) in myObject" :key=key.id :value="value">
      {{ key }}
    </option>
  </select>
  <br />
  <br />
  <div v-for="country in myObject">

    <select v-model="selectedCategorySub">
      <option v-for="country in country"> {{ country }} </option>
    </select>
  </div>
</template>

The problem is that I can't display only one select option at the second part and overall, it is not working properly.


Solution

  • you could use the model from selectedCategoryProducts to make populate the list of options. Because it will be empty initially, you can add a v-if="selectedCategoryProducts" to the select element to no show it unless the first option is selected. No need for using computed.

    <select v-model="selectedCategorySub" v-if="selectedCategoryProducts">
      <option  v-for="option in selectedCategoryProducts">{{ option }}</option>
    </select>
    

    sfc example