Skip to content

Instantly share code, notes, and snippets.

@entioentio
Created July 20, 2021 14:05
Show Gist options
  • Save entioentio/83e4bd4f759669eda6898292544e3e52 to your computer and use it in GitHub Desktop.
Save entioentio/83e4bd4f759669eda6898292544e3e52 to your computer and use it in GitHub Desktop.
Wrapper for vue-multiselect that repositions the tags list on container element's scroll
<template>
<multiselect
ref="originalMultiselect"
v-bind="$attrs"
v-on="listeners"
class="position-relative"/>
</template>
<script>
import Multiselect from 'vue-multiselect'
export default {
name: 'MultiselectRepositionable',
inheritAttrs: false,
props: {
reposition: {
type: Boolean,
default: false
},
scrollableContainerSelector: {
type: [Boolean, String],
default: false
}
},
components: {
Multiselect
},
computed: {
listeners() {
return {
...this.$listeners,
open: () => this.onOpen()
}
}
},
data () {
return {
scrollableContainer: null
}
},
methods: {
onOpen() {
this.repositionDropDown();
},
repositionDropDown() {
const { top, height } = this.$el.getBoundingClientRect();
const ref = this.$refs.originalMultiselect;
if (ref) {
ref.$refs.list.style.width = `${this.$el.clientWidth}px`;
ref.$refs.list.style.position = 'fixed';
ref.$refs.list.style.bottom = 'auto';
ref.$refs.list.style.top = `${top + height}px`;
}
},
},
mounted() {
this.scrollableContainer =
this.scrollableContainerSelector
? document.querySelector(this.scrollableContainerSelector) || window
: window;
this.scrollableContainer.addEventListener('scroll', this.repositionDropDown, { passive: true });
},
destroyed() {
this.scrollableContainer.removeEventListener('scroll', this.repositionDropDown);
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment