Manish Mavi
Manish Mavi

Reputation: 53

Vue-MultiSelect Checkbox binding

The data properties of the multi-select component does not update on change. Check-boxes doesn't update on the front-end.

Expected Behavior: The check-boxes should get ticked, when clicked.

Link to code: https://jsfiddle.net/bzqd19nt/3/

<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>
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');
      option.checked = true;
      console.log(`${option.library}  Clicked!! ${option.checked}`);
    },

    onRemove(option) {
      console.log('Removed');
      option.checked = false;
      console.log(`${option.library}  Removed!! ${option.checked}`);
    }
  }
}).$mount('#app');

Upvotes: 5

Views: 16600

Answers (1)

Lana
Lana

Reputation: 1267

In your code you call onSelect and try to change the option argument of this function inside the function:

option.checked = true;

This affects only the local variable option (the function argument). And doesn't affect objects in options array in the data of the Vue instance, the objects bound with checkboxes. That's why nothing happens when you click on an option in the list.

To fix it find the appropriate element in options array and change it:

let index = this.options.findIndex(item => item.library==option.library);
this.options[index].checked = true;

Here is the code snippet with fix:

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);
    }
  }
}).$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/[email protected]/dist/vue-multiselect.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/[email protected]/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>

Upvotes: 9

Related Questions