javascriptvue.jsvuejs3vue-multiselect

How to make checkbox selected with v-model value for vue-multiselect


Question: on created selected option checkbox is not getting selected, i want checkbox to be selected irrespective checked true/false

Note: value model i always want without checked state into it

below image shows my problem(please see yellow area)

enter image description here

here is what i have tried:

new Vue({
    components: {
    Multiselect: window.VueMultiselect.default
    },
    data: {
    value: [],
    options: [
        {   language: 'JavaScript', library: 'Vue.js', checked: false },
      { language: 'JavaScript', library: 'Vue-Multiselect', checked: false },
      { language: 'JavaScript', library: 'Vuelidate', checked: false }
    ]
    },
  methods: {
    customLabel (option) {
      return `${option.library} - ${option.language}`
    },
    onSelect (option) {
        console.log("Added");
      let index = this.options.findIndex(item => item.library==option.library);
      this.options[index].checked = true;
      console.log(option.library + "  Clicked!! " + option.checked);
    },
    
    onRemove (option) {
        console.log("Removed");
      let index = this.options.findIndex(item => item.library==option.library);
      this.options[index].checked = false;
      console.log(option.library + "  Removed!! " + option.checked);
    }
  },
  created(){
       this.value = [{  language: 'JavaScript', library: 'Vue.js',checked:true }];
  }
}).$mount('#app')
* {
  font-family: 'Lato', 'Avenir', sans-serif;
}

.checkbox-label {
  display: block;
}

.test {
  position: absolute;
  right: 1vw;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://unpkg.com/vue-multiselect@2.0.2/dist/vue-multiselect.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/vue-multiselect@2.0.3/dist/vue-multiselect.min.js"></script>
<div id="app">
  <multiselect 
    select-Label=""
    selected-Label=""
    deselect-Label=""
    v-model="value" 
    :options="options"
    :multiple="true"
    track-by="library"
    :custom-label="customLabel"
    :close-on-select="false"
    @select=onSelect($event)
    @remove=onRemove($event)
    >
    <span class="checkbox-label" slot="option" slot-scope="scope" @click.self="select(scope.option)">
    {{ scope.option.library }}
      <input class="test" type="checkbox" v-model="scope.option.checked" @focus.prevent/>
      
    </span>
  </multiselect>
  <pre>{{ value }}</pre>
</div>

please help me thanks in advance!!


Solution

  • It's a bit hard to understand what you actually want but assuming:

    1. You want to render checkboxes
    2. You don't want checked field in the v-model (so it was added only to help render the checkboxes)

    You don't need checked property at all as the value can be easily replaced by simple check against the v-model. That way you can remove a lot of unnecessary code.

    See my example below:

    new Vue({
      components: {
        Multiselect: window.VueMultiselect.default
      },
      data: {
        value: [],
        options: [{
            language: 'JavaScript',
            library: 'Vue.js'
          },
          {
            language: 'JavaScript',
            library: 'Vue-Multiselect'
          },
          {
            language: 'JavaScript',
            library: 'Vuelidate'
          }
        ]
      },
      methods: {
        customLabel(option) {
          return `${option.library} - ${option.language}`
        },
        isSelected(option) {
          /* unfortunatelly following line does not work as VueMultiselect for some (strange) reason 
            fills the v-model array with copies instead of original objects contained in options
          */
          // return this.value.includes(option)
          return this.value.some((op) => op.library === option.library)
        }
      },
      created() {
        this.value.push(this.options[0])
      }
    }).$mount('#app')
    * {
      font-family: 'Lato', 'Avenir', sans-serif;
    }
    
    .checkbox-label {
      display: block;
    }
    
    .test {
      position: absolute;
      right: 1vw;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <link href="https://unpkg.com/vue-multiselect@2.0.2/dist/vue-multiselect.min.css" rel="stylesheet" />
    <script src="https://unpkg.com/vue-multiselect@2.0.3/dist/vue-multiselect.min.js"></script>
    <div id="app">
      <multiselect select-Label="" selected-Label="" deselect-Label="" v-model="value" :options="options" :multiple="true" track-by="library" :custom-label="customLabel" :close-on-select="false">
        <span class="checkbox-label" slot="option" slot-scope="scope">
        {{ scope.option.library }}
          <input class="test" type="checkbox" :checked="isSelected(scope.option)" @focus.prevent :key="scope.option.library" />
        </span>
      </multiselect>
      <pre>{{ value }}</pre>
    </div>