select2 icon indicating copy to clipboard operation
select2 copied to clipboard

Shadow DOM Issue: Selection Dropdown Hangs Open When Clicked Elsewhere On Page

Open rdusinaspotx opened this issue 5 years ago • 1 comments

As a user of Select2, I would like the dropdown menu to close when I click elsewhere on the page because this is the expected and natural behavior of selection dropdowns.

Expected Behavior: When a the selection dropdown is open and a click happens outside of the dropdown menu, the dropdown menu should close.

Actual Behavior: The dropdown does not close when a click event occurs outside of the open dropdown menu.

Steps To Reproduce: Create a Select2 element in the Shadow DOM and configure it to open a dropdown menu when a user is selecting an option. Click outside of the dropdown menu and Select2 element. The dropdown menu will hang open.

Notes: I consider this a bug and not a feature request because it seems that the default behavior of Select2 is that clicking outside of the dropdown menu closes it. JSFiddle: https://jsfiddle.net/mslocum/kfqd7nga/

rdusinaspotx avatar Feb 25 '20 18:02 rdusinaspotx

I've hit the same issue. Any workarounds?

Edit: For anyone interested I added this to my WebComponent constructor

// Listen to all clicks.  Close any open select2 elements (but avoid calling close on a select2 element if we're trying to open it!)
document.body.addEventListener('click', (event) => {
  // Look to see if we've clicked on a select2 enabled element
  const select2El = event.path.find((el) => el.dataset && el.dataset.select2Id);
  
  // If so, get the previousElementSibling (which will be the original <select> element)
  const selectEl = select2El && select2El.previousElementSibling;

  // The select2Id is injected by the select2 lib.   The select2Id will be falsey if we clicked on anything but a select2 enabled component.  We get this so we can avoid calling "close" on the select2 element we just clicked on (if indeed, we did click on one)
  const select2Id = selectEl && selectEl.dataset.select2Id;

  this.shadowRoot.querySelectorAll('select').forEach((el) => {
    // Close any unrelated select2 elements in this web component
     if (el.dataset.select2Id !== select2Id) {
       $(el).select2('close');
     }
  });
});

Richard-Walton avatar Apr 20 '20 14:04 Richard-Walton