'Toggle vue-multiselect close/open on button click

When I click on the button, multiselect opens. But when I click on the button a second time, the true / false values ​​flash and as a result, isOpen remains true. What am I doing wrong?

template:

<div id="app">
  <button @click="toggle">open and close later
  </button>
    <pre>{{ isOpen }}</pre>
  <multiselect 
    ref="multiselect"
    v-model="value" 
    :options="options"
    :multiple="true"
    track-by="library"
    :custom-label="customLabel"
    @close="isOpen = false"
    @open="isOpen = true"
    >
  </multiselect>
</div>

js:

new Vue({
    components: {
    Multiselect: window.VueMultiselect.default
    },
    data: {
    isOpen: false,
    value: { language: 'JavaScript', library: 'Vue-Multiselect' },
    options: [
        {   language: 'JavaScript', library: 'Vue.js' },
      { language: 'JavaScript', library: 'Vue-Multiselect' },
      { language: 'JavaScript', library: 'Vuelidate' }
    ]
    },
  methods: {
    toggle () {
        if (this.isOpen) {
        this.$refs.multiselect.$el.blur();
        this.isOpen = false;
      }
      else {
        this.$refs.multiselect.$el.focus();
        this.isOpen = true;
      }

    }
  }
}).$mount('#app')

https://jsfiddle.net/46s5aknt/



Solution 1:[1]

As I dug the source code of this component, unfortunately, I realized there is not any "legit" way to make works your requirement. @blur callback will be called no matter what. There is no way to regulate this behavior.

Workaround: some aspect of locking with a cooldown time...

new Vue({
  components: {
    Multiselect: window.VueMultiselect.default
  },
  data: {
  blocked: false,
  value: { language: 'JavaScript', library: 'Vue-Multiselect' },
  options: [
    { language: 'JavaScript', library: 'Vue.js' },
    { language: 'JavaScript', library: 'Vue-Multiselect' },
    { language: 'JavaScript', library: 'Vuelidate' }
  ]
},
  methods: {
    toggle () {
      if (!this.blocked) {
        this.$refs.multiselect.toggle();
      }
    },
    block () {
      this.blocked = true;
      setTimeout(() => {
        this.blocked = false;
      }, 200);
    }
  }
}).$mount('#app')

Solution 2:[2]

The problem here is that VueMultiselect closes when there is a click outside the component.

So when you press the click button (on your mouse) VueMultiselect closes and when you release the click button you are actually reopening VueMultiselect since isOpen was set to false in the close event.

So your button can only be an Open button.

Edit:

The best solution would be to hide the button when the VueMultiselect is open.

Solution 3:[3]

I know this is a old post but I just thought I'd add what I just figured out. (SIDE NOTE : This is most likely the incorrect way to do this... But it works)

I wanted to "close" the dropdown but I didn't want to have to click away to close the dropdown.

When going through the node modules for "vue-multi-select". I saw that with the use of refs you can actually call the "closeMultiSelect()" function to close the dropdown.

Below is an example of me wrapping the component in a div to apply the event listener to the whole component.

<div v-on:mouseleave="close()">
<vue-multi-select
    :ref="'multiselect'"
    v-model="selectedGroups"
    :selectOptions="options"
    :options="{multi : true}"
    :btnLabel="() => `Contact Groups`"
    :key="multiSelectComponentKey"
    search
></vue-multi-select>
</div>

Here is how I invoked the method to close the dropdown:

method:{
    close: function(){
        this.refs.multiselect.closeMultiSelect();  // this will close the dropdown
    }
}

The same concept can be used to open the dropdown:

method:{
    open: function(){
        this.refs.multiselect.openMultiSelect();  // this will open the dropdown
    }
}

And that's all... If this helped anyone awesome! If you know of a better way please let me know so we can update this with the correct way.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ursache
Solution 2
Solution 3 Collin Yarrington