davidstutz / bootstrap-multiselect

JQuery multiselect plugin based on Twitter Bootstrap.
https://davidstutz.github.io/bootstrap-multiselect/
Other
3.67k stars 1.98k forks source link

popupContainer cut by parent element #1164

Open JohnRDOrazio opened 3 years ago

JohnRDOrazio commented 3 years ago

I have placed some multiselects inside of a card, when I click a button near the bottom edge of the card to open the multiselect it is chopped off by the card. I see that popupContainer has a z-index of 999, however the z-index only competes with sibling elements. So in order to have the popupContainer show above everything else without getting chopped off, it would need to reside as a direct child of body.

However it is not enough to change

-this.$container.append(this.$popupContainer);
+$('body').append(this.$popupContainer);

because apparently something is expecting the this.$popupContainer to be a child of this.$container. Simply making it a child of the body element means bad things start happening. Could anyone point out what it is that expects the popupContainer to be a child of container? I've skimmed over the code but can't quite pinpoint it. I see this error in the console when trying to append to body:

Uncaught TypeError: Cannot read property 'setAttribute' of null
    at Object.onLoad (popper.js:1211)
    at popper.js:2521
    at Array.forEach (<anonymous>)
    at new t (popper.js:2519)
    at t.n.show (dropdown.js:175)
    at t.n.toggle (dropdown.js:126)
    at HTMLButtonElement.<anonymous> (dropdown.js:363)
    at Function.each (jquery.min.js:2)
    at S.fn.init.each (jquery.min.js:2)
    at S.fn.init.t._jQueryInterface [as dropdown] (dropdown.js:350)
onLoad @ popper.js:1211
(anonymous) @ popper.js:2521
t @ popper.js:2519
n.show @ dropdown.js:175
n.toggle @ dropdown.js:126
(anonymous) @ dropdown.js:363
each @ jquery.min.js:2
each @ jquery.min.js:2
t._jQueryInterface @ dropdown.js:350
(anonymous) @ dropdown.js:515
dispatch @ jquery.min.js:2
v.handle @ jquery.min.js:2

Some attribute is not able to be set correctly.

JohnRDOrazio commented 3 years ago

I guess this has been dealt with in issue #382 , where the solution given is to set overflow-y: visible on the container. In one comment however there is a solution would be more correct in my opinion:

Or - The plugin needs to undergo a major rewrite to create it ".multiselect-container" element in the document body then use position: absolute and JS to place it.

Originally posted by @Tyf0x in https://github.com/davidstutz/bootstrap-multiselect/issues/382#issuecomment-56909815

Of course it would be a bit of work, but this is how jQuery UI deals with this for example. Any kind of popup that should show above other contents is inserted at the body level. This would be the cleanest solution in my opinion, requiring a reworking of the plugin...