[Vuejs]-Vue JS Multiple filters, one array

0👍

You can modify the filterAry function to check each filter condition one by one as given below

let classes = {
  menu: [
    { topic: 'math', location: 'adadadas', price: 80, length: "120", time: "9:00", reviewStars: "3" },
    { topic: 'math', location: 'dsadassa', price: 90, length: "70", time: "11:00", reviewStars: "4" },
    { topic: 'math', location: 'dadass', price: 120, length: "30", time: "14:00", reviewStars: "1" },
    { topic: 'english', location: 'dasdsadas', price: 110, length: "45", time: "13:00", reviewStars: "2" },
    { topic: 'english', location: 'fsafasf', price: 90, length: "75", time: "11:00", reviewStars: "4" },
    { topic: 'english', location: 'fafasa', price: 90, length: "100", time: "17:00", reviewStars: "2" },
    { topic: 'english', location: 'fsasada', price: 130, length: "90", time: "15:00", reviewStars: "3" },
    { topic: 'piano', location: 'dsadsadsads', price: 120, length: "", time: "50", time: "13:00", reviewStars: "4" },
    { topic: 'piano', location: 'dsadasddsadsadas', price: 140, length: "40", time: "12:00", reviewStars: "1" }
  ],
  input: {
    topic: '',
    location: 'All',
    topics: 'All',
    price: 'All',
    reviews: 'All'
  },
  newAry: [],
  otherAry: [],
  filterText: null
};


var searchBar = new Vue({
  el: '#searchBar',
  data: classes,
  computed: {
    menuArray() {
      let vm = this
      let array = new Set()
      vm.menu.forEach(function (item) {
        array.add(item.location)
      })
      console.log(array)
      return vm.newAry = Array.from(array)

    },

    menuArrayReview() {
      let vm = this
      let array = new Set()
      vm.menu.forEach(function (item) {
        array.add(item.reviewStars)
      })
      console.log(array)
      return vm.newAry = Array.from(array)

    },
    menuArrayTopic() {
      let vm = this
      let array = new Set()
      vm.menu.forEach(function (item) {
        array.add(item.topic)
      })
      console.log(array)
      return vm.newAry = Array.from(array)

    },
    menuArrayPrice() {
      let vm = this
      let array = new Set()
      vm.menu.forEach(function (item) {
        array.add(item.price)
      })
      console.log(array)
      return vm.newAry = Array.from(array)

    },

    filterTypeTopic() {
      let vm = this
      if (vm.input.topic !== 'All') {
        return vm.otherAry.filter(function (item) {
          return item.topic === vm.input.topic
        })
      } else {
        return vm.otherAry
      }
    },

    filterTypePrice() {
      let vm = this
      if (vm.input.price !== 'All') {
        return vm.otherAry.filter(function (item) {
          return item.price === vm.input.price
        })
      } else {
        return vm.otherAry
      }
    },

    filterTypeReviews() {
      let vm = this
      if (vm.input.review !== 'All') {
        return vm.otherAry.filter(function (item) {
          return item.reviewStars === vm.input.review
        })
      } else {
        return vm.otherAry
      }
    },

    filterAryTopic() {
      let vm = this
      if (vm.input.topic) {
        return vm.filterTypeTopic().filter(function (item) {
          let content = item.topic.toLowerCase()
          let keyword = vm.input.topic.toLowerCase()
          return content.indexOf(keyword) !== -1
        })
      } else {
        return vm.filterTypeTopic
      }

    },

    filterAryPrice() {
      let vm = this
      if (vm.input.price) {
        return vm.filterTypePrice.filter(function (item) {
          let content = item.price.toLowerCase()
          let keyword = vm.input.price.toLowerCase()
          return content.indexOf(keyword) !== -1
        })
      } else {
        return vm.filterTypePrice
      }

    },

    filterAryReviews() {
      let vm = this
      if (vm.input.review) {
        return vm.filterTypeReviews().filter(function (item) {
          let content = item.reviewStars.toLowerCase()
          let keyword = vm.input.review.toLowerCase()
          return content.indexOf(keyword) !== -1
        })
      } else {
        vm.menu = vm.filterTypeReviews()
      }
    },

    filterType() {
      let vm = this
      if (vm.input.location !== 'All') {
        return vm.otherAry.filter(function (item) {
          return item.location === vm.input.location
        })
      } else {
        return vm.menu
      }
    },

    filterAry() {
      let vm = this
      return vm.menu.filter(function(value){
        if(vm.input.topics.length && vm.input.topics!="All" && value.topic!=vm.input.topics) return false  
        if(vm.input.reviews.length && vm.input.reviews!="All" && value.reviewStars!=vm.input.reviews) return false  
        if(vm.input.price && vm.input.price!="All" && value.price!=vm.input.price) return false 
        if(vm.input.topic.length){
          return value.topic.indexOf(vm.input.topic) > -1
        }
      return true
      })
      
    },


    getAry() {
      let vm = this
      return vm.otherAry
    }
  },
  mounted: function () {
    newAry = classes;
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="searchBar">
    <div class="display-3 text-center my-5 text-secondary">Activities!  </div>
    <div class="container w-75">
      <div class="row mb-3">
        <div class="col-md-4">
          <div>
            <select name=""  class="form-control" v-model.trim="input.price">
              <option value="All" selected>All</option>
              <option :value="item" v-for="item in menuArrayPrice">{{item}}</option>
            </select>
            <select name=""  class="form-control" v-model.trim="input.topics">
              <option value="All" selected>All</option>
              <option :value="item" v-for="item in menuArrayTopic">{{item}}</option>
            </select>
            <select name=""  class="form-control" v-model.trim="input.reviews">
              <option value="All" selected>All</option>
              <option :value="item" v-for="item in menuArrayReview">{{item}}</option>
            </select>
          </div>
        </div>
        <div class="col-md-8">
          <input type="text" name=""  class="form-control" v-model.trim="input.topic" placeholder="search topics">
        </div>
      </div>
    </div>

    <div class="container w-75 mb-5">
      <div class="row">
        <div class="col-md-4" v-for="item in filterAry" >
          <ul class="course list-group mb-3">
            <li class="list-group-item text-accent h4 font-weight-bold">{{item.location}}</li>
            <li class="list-group-item text-secondary song-item d-flex flex-column ">
              {{item.topic}}{{item.price}}
          </ul>
        </div>
      </div>
    </div>
  </div>

0👍

I see what you’ve tried to do here, but I think you need to get a new and fresh look at it. Chaining filters would be correct aproach here, just need to get it working it right with your data set.

Probably this type of architecture would work

data() {
  return {
    topic: 'All',
    location: 'All',
    // and rest of filterable parameters
  }
},

computed: {
    filteredAry () {
      const { topic, location } = this
      const filteredMenu = Array.from(menu);
      if (topic !== 'All') {
        filteredMenu.filter(item => item.topic === topic)
      }
      // ... and so on for all possible filter values
      return filteredMenu
    },
  },

and then you use filteredAry in your v-for loop to display data

Leave a comment