question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Vue multiselect inside of element with scrollbar

See original GitHub issue

Hi, firstly thank you for a great plugin, it’s really great.

I found one issue with using vue vue-multiselect inside of elements with overflow:auto. After to expand, vue multiselect is still inside of the element with overflow auto, which is not how the standard <select> works.

Fiddle: https://jsfiddle.net/jqofkzxc/3078/

Expected behaviour: After to expand the vue-multiselect (.multiselect__content-wrapper) shouldn’t cause the .modal-body to expand.

Possible fix: This could be achieved by setting it outside of element with overflow (.modal-body in that case), and using position absolute + dynamically counted left/top css.

Why? It would make it much easier to use it in replacement to standard <select> without any hacks.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

11reactions
me-singhcommented, Mar 25, 2019

Is there any way we can overcome this issue. I want dropdown to appear above overflow (it is blocked by overflow).

4reactions
Kocalcommented, Aug 6, 2020

I’ve used @sigma207 directive, but unfortunately I’ve got two issues with it:

  • when scrolling, the multiselect does not move and that’s weird
  • the parent element lose its height since the multiselect is in position: fixed, so next elements are moved up and this is not wanted

I’ve patched it to use position: absolute instead of fixed, and used an invisible clone to preserve the parent height:

export default {
  install(Vue) {
    Vue.directive('select-overflow', {
      inserted: (el, _binding, vnode) => {
        let originalWidth
        let originalPosition
        let originalZIndex
        let selectIsOpen = false
  
        // will be used as a placeholder, in order to fix parent height issue (due to position relative)
        const clone = el.cloneNode(true);
        clone.style.visibility = 'hidden';

        vnode.child.$watch('isOpen', isOpen => {
          selectIsOpen = isOpen
          if (isOpen) {
            const { offsetWidth } = el
            originalWidth = el.style.width
            originalPosition = el.style.position
            originalZIndex = el.style.zIndex
            el.style.width = `${offsetWidth}px`
            el.style.position = 'absolute'
            el.style.zIndex = 2
            el.parentNode.insertBefore(clone, el.nextSibling); // insert after el
          } else {
            el.style.position = originalPosition
            el.style.width = originalWidth
            el.style.zIndex = originalZIndex
            clone.parentNode.removeChild(clone);
          }
        })

        window.addEventListener('wheel', event => {
          if (selectIsOpen) {
            // disabled outside scroll when select is open
            event.stopPropagation()
          }
        }, true)
      },
    })
  }
}

EDIT: I’ve encountered some issues with the vue-multiselect’s position in a scrollable element, which was not displayed properly. I’m now setting position: relative to the parent element and it’s now working well:

// See https://github.com/shentao/vue-multiselect/issues/723#issuecomment-596988587
// and https://gist.github.com/sigma207/b9300fe12a996c07b2389ee03c1464ed

export const directiveOverflow = {
  inserted: (el, _binding, vnode) => {
    let originalParentPosition;
    let originalWidth;
    let originalPosition;
    let originalZIndex;
    let selectIsOpen = false;

    // will be used as a placeholder, in order to fix parent height issue (due to position relative)
    const clone = el.cloneNode(true);
    clone.style.visibility = 'hidden';

    vnode.child.$watch('isOpen', (isOpen) => {
      selectIsOpen = isOpen;

      if (isOpen) {
        const { offsetWidth } = el;
        originalParentPosition = el.parentElement.style.position;
        originalWidth = el.style.width;
        originalPosition = el.style.position;
        originalZIndex = el.style.zIndex;
        el.parentElement.style.position = 'relative';
        el.style.width = `${offsetWidth}px`;
        el.style.position = 'absolute';
        el.style.zIndex = 9999;
        el.parentNode.insertBefore(clone, el.nextSibling); // insert after el
      } else {
        el.parentElement.style.position = originalParentPosition;
        el.style.position = originalPosition;
        el.style.width = originalWidth;
        el.style.zIndex = originalZIndex;
        clone.parentNode.removeChild(clone);
      }
    });

    window.addEventListener(
      'wheel',
      (event) => {
        if (selectIsOpen) {
          // disabled outside scroll when select is open
          event.stopPropagation();
        }
      },
      true
    );
  },
};
Read more comments on GitHub >

github_iconTop Results From Across the Web

vue-multiselect dropdown list without horizontal scrollbar
One simple solution would be to remove fit-content from .multiselect__element : .multiselect__content-wrapper /*, .multiselect__element ...
Read more >
Vue-Multiselect | Vue Select Library
Probably the most complete selecting solution for Vue.js, without jQuery.
Read more >
Infinite Scroll - Vue Select
Vue Select doesn't ship with first party support for infinite scroll, but it's possible to implement by hooking into the open , close...
Read more >
Vue MultiSelect Component - PrimeFaces
MultiSelect is used to select multiple items from a collection.
Read more >
Vue MultiSelect Component | Kendo UI for Vue - Telerik
Kendo UI for Vue MultiSelect can contain thousands of options in its popup list. With the Virtualization option enabled, the scrolling of many...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found