Search code examples
vue.jsvuejs2vue-componentvue-multiselect

vue-multiselect two controls one source with no item overlapping


Hi vue and js experts!

I have a list of values ["A", "B", "C", "D"]

a user needs to pick values into two lists "List1" and "List2". Values in the lists should not overlap. Let say user picks "A" for "List1", the option "A" should become unavailable for picking in "List2"

Currently I am using two instances of Vue-Mulitselect component which share same list of options. It works fine but values in "List1" and "List2" can overlap (e.g. user can pick 'A' in both lists).

Please advise how bind two multiselect to share same options list with no overlapping?

<template>
  <div>
    <multiselect v-model="List1" :options="options"></multiselect>
    <multiselect v-model="List2" :options="options"></multiselect>
  </div>
</template>

<script>
  import Multiselect from 'vue-multiselect'

  export default {
    components: { Multiselect },
    data () {
      return {
        List1: null,
        List2: null, 
        options: ['A', 'B', 'C', 'D']
      }
    }
  }
</script>

Solution

  • You can use computed property:

    <multiselect v-model="List1" :options="options1"></multiselect>
    <multiselect v-model="List2" :options="options2"></multiselect>
    
     computed: {
        options1 () {
          return this.options.filter(item => item !== this.List2)
        },
        options2 () {
          return this.options.filter(item => item !== this.List1)
        }
     }
    

    In your case, it's single selected. If it's multiple select, you should change

    return this.options.filter(item => this.List2.includes(item)
    

    Check a demo