0

I'm learning vue.js and I'm trying to make a case study search with multiple dropdowns and button search. I need to find out a filter function that will filter the object list based on a selection from several dropdowns with the trigger button search.

I have the code that I have written below, but this filter works in realtime. When one of the dropdowns is selected it will display the search results. But what I want is that the search results appear when after selecting several dropdowns and must click the search button, then the results appear.

I've been looking for some references and tried but still not getting the results I want.

new Vue({
  el: '#app',
  data: {
    selectedType: '',
    selectedCountry: '',
    selectedYear: '',
    items: [
      {
        name: 'Nolan',
        type: 'mercedes',
        year: '2020',
        country: 'england'
      },
      {
        name: 'Edgar',
        type: 'bmw',
        year: '2020',
        country:'belgium'
      },
      {
        name: 'John',
        type: 'bmw',
        year: '2019',
        country: 'england'
      },
      {
        name: 'Axel',
        type: 'mercedes',
        year: '2020',
        country: 'england'
      }
    ]
  },
  computed: {
    searchItem: function () {
      let filterType= this.selectedType,
          filterCountry = this.selectedCountry,
          filterYear = this.selectedYear
      
      return this.items.filter(function(item){
        let filtered = true
        if(filterType && filterType.length > 0){
          filtered = item.type == filterType
        }
        if(filtered){
          if(filterCountry && filterCountry.length > 0){
            filtered = item.country == filterCountry
          }
        }
        if(filtered){
          if(filterYear && filterYear.length > 0){
            filtered = item.year == filterYear
          }
        }
        return filtered
      })
    }
  }
})
.list-item{
  margin-top:50px;
}

.card{
  box-shadow:0px 10px 16px rgba(0,0,0,0.16);
  width:400px;
  padding:20px 30px;
  margin-bottom:30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.1/vue.js"></script>

<div id="app">
  <select v-model="selectedType">
    <option value="mercedes">Mercedes</option>
    <option value="bmw">BMW</option>
  </select>
  
  <select v-model="selectedCountry">
    <option value="belgium">Belgium</option>
    <option value="england">England</option>
  </select>
  
  <select v-model="selectedYear">
    <option value="2019">2019</option>
    <option value="2020">2020</option>
  </select>
  
  <button>Search</button>
  
  <div class="list-item" v-for="item in searchItem">
    <div class="card">
      <p>Name: {{ item.name }}</p>
      <p>Car: {{ item.type }}</p>
      <p>Year: {{ item.year }}</p>
      <p>Country: {{ item.country }}</p>
    </div>
  </div>
</div>

1
  • computed is reactive. What that means is that whenever the reactive references in your computed change, the computed is rerun and the template updates. If you don't want reactivity, use a method instead and run it according to your own logic. Commented Jan 8, 2021 at 8:18

1 Answer 1

1

Instead of using computed, consider defining a method for the filtering.

See the following as an example

new Vue({
  el: '#app',
  data: {
    selectedType: '',
    selectedCountry: '',
    selectedYear: '',
    items: [{
        name: 'Nolan',
        type: 'mercedes',
        year: '2020',
        country: 'england'
      },
      {
        name: 'Edgar',
        type: 'bmw',
        year: '2020',
        country: 'belgium'
      },
      {
        name: 'John',
        type: 'bmw',
        year: '2019',
        country: 'england'
      },
      {
        name: 'Axel',
        type: 'mercedes',
        year: '2020',
        country: 'england'
      }
    ],
    searchResult: [],
  },
  methods: {
    search: function() {
      let filterType = this.selectedType,
        filterCountry = this.selectedCountry,
        filterYear = this.selectedYear

      this.searchResult = this.items.filter(function(item) {
        let filtered = true
        if (filterType && filterType.length > 0) {
          filtered = item.type == filterType
        }
        if (filtered) {
          if (filterCountry && filterCountry.length > 0) {
            filtered = item.country == filterCountry
          }
        }
        if (filtered) {
          if (filterYear && filterYear.length > 0) {
            filtered = item.year == filterYear
          }
        }
        return filtered
      })
    }
  },
  mounted() {
    this.search()
  }
})
.list-item {
  margin-top: 50px;
}

.card {
  box-shadow: 0px 10px 16px rgba(0, 0, 0, 0.16);
  width: 400px;
  padding: 20px 30px;
  margin-bottom: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.1/vue.js"></script>

<div id="app">
  <select v-model="selectedType">
    <option value="" disabled selected hidden>Type</option>
    <option value="mercedes">Mercedes</option>
    <option value="bmw">BMW</option>
  </select>

  <select v-model="selectedCountry">
    <option value="" disabled selected hidden>Country</option>
    <option value="belgium">Belgium</option>
    <option value="england">England</option>
  </select>

  <select v-model="selectedYear">
    <option value="" disabled selected hidden>Year</option>
    <option value="2019">2019</option>
    <option value="2020">2020</option>
  </select>

  <button @click="search">Search</button>

  <div class="list-item" v-for="item in searchResult">
    <div class="card">
      <p>Name: {{ item.name }}</p>
      <p>Car: {{ item.type }}</p>
      <p>Year: {{ item.year }}</p>
      <p>Country: {{ item.country }}</p>
    </div>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

3 Comments

It's good! by the way, I want to ask about placeholders. In the normal select dropdown, when we give the option <option selected> Year </option> it will be the placeholder. But I tried it like that in my code, it doesn't appear. How do I display it?
@frankfurt And regarding your question about placeholder, you can add an option with disabled selected hidden. Please see the edit
@frankfurt If you had something liketype:"mercedes, audi" and you wanted it o come up when the dropdown showed mercedes, how would you change it so it didn't only look for exact matches? Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.