Skip to content

Prop to close the dropdown when the component looses focus - aka clicking elsewhere on the page #1754

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
runxc1 opened this issue Feb 8, 2023 · 3 comments

Comments

@runxc1
Copy link

runxc1 commented Feb 8, 2023

Is your feature request related to a problem? Please describe.
Yes this is a usability issue, I have a v-select where both searchable is false as well as clearable. When the user opens the dropdown I want it to close when they select something else on the page.

Describe alternatives you've considered
I've looked for a blur event but only find one on the search and as there is no search there is no blur event saying when the component has lost focus.

@dpmango
Copy link

dpmango commented Mar 24, 2023

Would be really nice to have bugifx for this issue.
When you open multiple selects, options collapase. Especially annoying when using multiple selects and close-on-select: false

You can visually make it looks like closed options when they are open

<template>
  <div
    class="select"
    ref="containerRef"
    :class="[
      opened && 'is-opened',
    ]"
    @click="opened = true"
  >
    <vue-select
      @open="opened = true"
      @close="opened = false"
    />
  </div>
</template>

<script setup lang="ts">
import { defineComponent } from 'vue'
import { onClickOutside } from '@vueuse/core'

const containerRef = ref(null)
onClickOutside(containerRef, () => {
  opened.value = false
})


const opened = ref(false)

</script>

<style lang="scss" scoped>
.select {
  position: relative;
  &:not(.is-opened) {
    :deep(.vs__dropdown-menu) {
      opacity: 0 !important;
      pointer-events: none !important;
    }
    :deep(.vs__open-indicator) {
      transform: none;
    }
  }
}
</style>

@gregdev
Copy link

gregdev commented Apr 29, 2023

I worked around this by leaving searchable as true and then just hiding the search input:

.vs__search {
    opacity: 0;
    pointer-events: none;
}

Not ideal but it works.

@faran-tenovos
Copy link

faran-tenovos commented Aug 22, 2023

@gregdev approach does work but you loose placeholders as they are not visible what I did as a hack was extended the component added an blur on the input and used that in vue.use for vue app

import Component from 'vue-class-component';
import { VueSelect } from 'vue-select';

@Component({
  name: 'ExtendedVueSelect',
  extends: VueSelect,
  created() {
    this.$on('close', this.onCloseFix);
  },
})
class ExtendedVueSelect extends Vue {
  onCloseFix() {
    // Attempt to access the nested input element and call blur on it for fixing bug
    const inputElement = this.$el.querySelector('input');
    if (inputElement) {
      inputElement.blur();
    }
  }
}

export default {
  install: (v: typeof Vue) => {
    // Register the extended component instead of the original VueSelect
    v.component('VSelect', ExtendedVueSelect);
  },
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants