Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

323
Views
FIltering results based on several Multiselect boxes, vue

I have a vue component where I'm currently successfully showing results from a data object, and I've also successfully created several multiselect boxes. My issue is filtering.

I know how I can set a single value from the multiselect and compare it (using v-if) in order to show certain results in an HTML div, but I'm completely lost now on how to do proper filtering based on multiple Multiselects (especially since several of them allow multiple options that store the values in arrays)

I'm putting my snippet below, but how can I properly make it so that I can filter results based on all values in the corresponding v-models for the multiselects, while making sure that if "All stores" or "All areas" is selected, it allows all values for that selection?

-- In other words, if the user doesn't ake a selection and the multiselect is left on the placeholder, all values for that select would be allowed to show in the DOM (based on other filters first)

new Vue({
  el: "#app",
  components: {Multiselect: window.VueMultiselect.default},
  data: {
    selectedOutput: '',
    selectedAreas:[],
    selectedStores: [],
    selectedCategories: [],
    selectedShifts: [],
    shifts: [
      {id: 1, name: "First"},
      {id: 2, name: "Second"}
    ],
    categories: [
      {id: 1, name: "electronics"},
      {id: 1, name: "home"},
      {id: 1, name: "auto"},
    ],
    outputOptions: [
      {id:1, name: "Sold"},
      {id:2, name: "Purchased"}
    ],
    areas: [
        {value: 1, name: "East"},
        {value: 1, name: "West"},
    ],
    stores: [
        {value: 1, name: "One"},
        {value: 2, name: "Two"}
    ],
    workNumbers: [
        {
          "Adam": {
            "name": "Adam",
            "title": "Manager",
            "shift": "First",
            "category": "electronics",
            "area" : "East",
            "store": "One",
            "sold": 140,
            "purchased": 15
          },
          "Ben": {
            "name": "Ben",
            "title": "Manager",
            "shift": "First",
            "category": "electronics",
            "area" : "East",
            "store": "One",
            "sold": 225,
            "purchased": 77
          },
          "Suzie": {
            "name": "Suzie",
            "title": "Manager",
            "shift": "Second",
            "category": "home",
            "area" : "West",
            "store": "Two",
            "sold": 124,
            "purchased": 55
          },
          "Reg": {
            "name": "Reg",
            "title": "Manager",
            "shift": "Second",
            "category": "home",
            "area" : "West",
            "store": "Two",
            "sold": 66,
            "purchased": 36
          },
          "Kelly": {
            "name": "Kelly",
            "title": "Manager",
            "shift": "Second",
            "category": "home",
            "area" : "West",
            "store": "Two",
            "sold": 55,
            "purchased": 2
          },
        }
    ]
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-multiselect/3.0.0-alpha.2/vue-multiselect.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/vue-multiselect/3.0.0-alpha.2/dist/vue-multiselect.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedOutput"
      :options="outputOptions"
      :multiple="false"
      :close-on-select="true"
      label="name"
      track-by="name"
      @input="checkOutput"
    ></multiselect>
</div>
<div class="uk-width-2-10" style="position:relative;">
    <multiselect
      v-model="selectedShifts"
      :options="shifts"
      :multiple="true"
      :close-on-select="true"
      placeholder="All shifts"
      label="name"
      track-by="name"
    ></multiselect>
</div>
<div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedCategories"
      :options="categories"
      :multiple="true"
      :close-on-select="true"
      placeholder="All categories"
      label="name"
      track-by="id"
    ></multiselect>
</div>
<div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedAreas"
      :options="areas"
      :multiple="true"
      :close-on-select="true"
      placeholder="All areas"
      label="name"
      track-by="name"
    ></multiselect>
</div>
<div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedstores"
      :options="stores"
      :multiple="true"
      :close-on-select="true"
      placeholder="All stores"
      label="name"
      track-by="value"
    ></multiselect>
</div>

    <table>
    <tbody v-if="selectedOutput.name === 'Sold'">
      <tr v-for="(value, employee) in workNumbers"  :key="employee">
        <!-- this is where I need a condition to show based on filters, I believe-->
        <td>{{name}} - {{sold}}</td>
      </tr>
    </tbody>
    <tbody v-else-if="selectedOutput.name === 'Purchased'">
      <tr v-for="(value, employee) in workNumbers"  :key="employee">
        <!-- this is where I need a condition to show based on filters, I believe-->
        <td>{{name}} - {{purchased}}</td>
      </tr>
    </tbody>
    </table>
</div>

UPDATE:

Now I've moved to another table which is similar but it's looping around different objects in order to create a different model that is also passed through a function for a modal.

<tbody v-if="selectedOutput.name === 'Cubes'">
  <tr v-for="(value, employee) in workNumbers"  :key="employee">
    <td v-for="date in dates" :key="date" >
      <div v-for="(dateSpecificData, dateValue) in value.dates" :key="dateValue" @click="showModal(dateSpecificData)"   :style="'background: ' + (dateSpecificData.unavailable > 0 ? '#f7a7a3' : '#a8f0c6')">
        <div v-if="dateValue == date ">
          @{{dateSpecificData.sold}}
        </div>
      </div>
    </td>
  </tr>
</tbody>
over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

You can define a computed-property that returns the filtered list according to the params:

new Vue({
  el: "#app",
  components: { Multiselect: window.VueMultiselect.default },
  data: () => ({
    selectedOutput: '',
    outputOptions: [ {id:1, name: "Sold"}, {id:2, name: "Purchased"} ],
    selectedShifts: [],
    shifts: [ {id: 1, name: "First"}, {id: 2, name: "Second"} ],
    selectedCategories: [],
    categories: [ {id: 1, name: "electronics"}, {id: 2, name: "home"}, {id: 3, name: "auto"} ],
    selectedAreas:[],
    areas: [ {value: 1, name: "East"}, {value: 1, name: "West"} ],
    selectedStores: [],
    stores: [ {value: 1, name: "One"}, {value: 2, name: "Two"} ],
    workNumbers: [
      {
        "Adam": { "name": "Adam", "title": "Manager", "shift": "First", "category": "electronics", "area" : "East", "store": "One", "sold": 140, "purchased": 15 },
        "Ben": { "name": "Ben", "title": "Manager", "shift": "First", "category": "home", "area" : "West", "store": "Two", "sold": 225, "purchased": 77 },
        "Suzie": { "name": "Suzie", "title": "Manager", "shift": "Second", "category": "electronics", "area" : "East", "store": "One", "sold": 124, "purchased": 55 },
        "Reg": { "name": "Reg", "title": "Manager", "shift": "Second", "category": "home", "area" : "West", "store": "Two", "sold": 66, "purchased": 36 },
        "Kelly": { "name": "Kelly", "title": "Manager", "shift": "Second", "category": "auto", "area" : "West", "store": "Two", "sold": 55, "purchased": 2 }
      }
    ]
  }),
  methods: {
    filtedSelectedHelper(arr = [], val) {
      return arr.length ? arr.some(({ name }) => name === val) : true;
    }
  },
  computed: {
    filteredWorkNumbers () {
      const ouput = this.selectedOutput;
      const filteredList = 
        this.workNumbers
          .flatMap(Object.values)
          .filter(({ shift, category, area, store }) => 
            this.filtedSelectedHelper(this.selectedShifts, shift) &&
            this.filtedSelectedHelper(this.selectedCategories, category) &&
            this.filtedSelectedHelper(this.selectedAreas, area) &&
            this.filtedSelectedHelper(this.selectedStores, store) 
          );
       return !this.selectedOutput 
         ? filteredList.map(({ name, sold, purchased }) => 
             `${name} - ${sold} - ${purchased}`
           )
         : this.selectedOutput.name === "Sold"
           ? filteredList.map(({ name, sold }) => 
               `${name} - ${sold}`
             )
           : filteredList.map(({ name, purchased }) => 
               `${name} - ${purchased}`
             )
    }
  }
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-multiselect@2.1.0"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-multiselect@2.1.0/dist/vue-multiselect.min.css">

<div id="app">
  <div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedOutput"
      :options="outputOptions"
      :multiple="false"
      :close-on-select="true"
      label="name"
      track-by="name"
    ></multiselect>
  </div>
  <div class="uk-width-2-10" style="position:relative;">
    <multiselect
      v-model="selectedShifts"
      :options="shifts"
      :multiple="true"
      :close-on-select="true"
      placeholder="All shifts"
      label="name"
      track-by="name"
    ></multiselect>
  </div>
  <div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedCategories"
      :options="categories"
      :multiple="true"
      :close-on-select="true"
      placeholder="All categories"
      label="name"
      track-by="id"
    ></multiselect>
  </div>
  <div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedAreas"
      :options="areas"
      :multiple="true"
      :close-on-select="true"
      placeholder="All areas"
      label="name"
      track-by="name"
    ></multiselect>
  </div>
  <div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedStores"
      :options="stores"
      :multiple="true"
      :close-on-select="true"
      placeholder="All stores"
      label="name"
      track-by="value"
    ></multiselect>
  </div>
  <table>
    <tbody>
      <tr v-for="str in filteredWorkNumbers" :key="str"><td>{{str}}</td></tr>
    </tbody>
  </table>
</div>

Resources:

https://vuejs.org/v2/guide/computed.html

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!