Tyler Morales
Tyler Morales

Reputation: 1830

How to add multiple filters on a Vue component's data?

I am trying to add multiple filters to a component. For example, a user can select a category and the results will be filtered. Additionally, since I have a search filter implement, how can I combine other filters with the join filter? For example, If I type 'Winter', and select a category that does not contain winter (a holidays filters), no results would show.

I've tried looking this up on Google, but I am only able to implement one filter at a time.

UPDATE I changed my computed properites to be a general filteredItems array. Now, I am able to set filters, however, when first load the page, nothing appears until I select a filter. Any ideas on how this can be fixed?

<template>
  <div class="cards">
    <CountdownCard
      v-for="(event, index) in filteredItems"
      :key="index"
      :event="event"
    />
  </div>
</template>

<script>
import CountdownCard from '@/components/CountdownCard'
import EventBus from '@/components/EventBus'

export default {
  components: {
    CountdownCard
  },
  data() {
    return {
      events: [
        {
          title: 'Autum',
          date: 'September 22, 2020',
          emoji: '🍂',
          type: 'holiday',
          year: 2020,
          month: 8,
          day: 22,
          hour: 0,
          minute: 0
        },
        {
          title: 'Winter',
          date: 'December 21, 2020',
          emoji: '⛄️',
          type: 'holiday',
          year: 2020,
          month: 11,
          day: 21,
          hour: 0,
          minute: 0
        }
      updateSearch: ''
    }
  },
  mounted() {
    EventBus.$on('search-countdowns', search => {
      this.updateSearch = search
    })
  },
  computed: {
    filteredItems: function() {
      return this.events
        .filter(event => {
          return event.title
            .toLowerCase()
            .includes(this.updateSearch.toLowerCase())
        })
        .filter(event => {
          return event.type == this.filter
        })
    }
  }
}
</script>

As you can see, I have a filteredHolidays filter that, when a button is clicked, would filter out any non-holiday results and display only holidays.

Here is the button component, that when clicked, should filter the data in my first component

<template>
  <button>{{ filter.name }}</button>
</template>

<script>
export default {
  props: {
    filter: {
      type: Object,
      required: true
    }
  }
}
</script>

Upvotes: 1

Views: 3464

Answers (1)

Tyler Morales
Tyler Morales

Reputation: 1830

Instead of listing multiple computed properties for each filter, make a general computed property called filteredItems and loop through that in the template. v-for="(event, index) in filteredItems"

computed: {
    filteredItems: function() {
      return this.events
        .filter(event => {
          return event.title
            .toLowerCase()
            .includes(this.updateSearch.toLowerCase())
        })
        .filter(event => {
          return event.type == this.filter
        })
    }
  }

Upvotes: 2

Related Questions