bootbox
bootbox copied to clipboard
Modal is unexpectedly closed when clicking on it, moving outside while keeping clicked, and releasing.
This is generating some complaints from out clients, since it's easy to perform an action like this. But we don't want to disable the choice to close the modal upon clicking on the backdrop.
I tried using the onHide callback, but both target and currentTarget refer to the modal occupying the whole viewport, not just the modal box.
Any idea on how to fix this issue?
Not really.
In theory, Bootstrap's events can be canceled (see https://getbootstrap.com/docs/5.2/getting-started/javascript/#events), but as you've seen and as noted in the Bootstrap docs:
All modal events are fired at the modal itself
Possibly hooking into an event when the user starts clicking and recording which element the mouse-down started at, then comparing that to the element at mouse-end, could work, but given that clicks propagate through the document stack means that isn't going to give you a very accurate answer to the question of "what was really being clicked?".
I'm open to suggestions, but we mostly just hook into Bootstrap's events within Bootbox, so there's not much to override at the moment.
Thank you for your quick reply!
I'll try to implement what you suggested, since it seems it's the only way for now. It would be great if this was not the default behaviour. Actually the Bootstrap modal doesn't behave like that, despite Bootbox being based on it. But we don't want to quit using Bootbox since it's heavily used in our platform, and aside from that issue, we like it.
Can you elaborate on what you mean by
Actually the Bootstrap modal doesn't behave like that
This might help here - https://stackoverflow.com/questions/16152073/prevent-bootstrap-modal-from-disappearing-when-clicking-outside-or-pressing-esca
Can you elaborate on what you mean by
Actually the Bootstrap modal doesn't behave like that
Sure!, if you launch this Bootstrap modal: https://getbootstrap.com/docs/4.3/components/modal/#live-demo you don't get the undesired behaviour I mean, that is you click on the modal, keep clicked, move mouse pointer outside and release, the modal won't close.
Can you elaborate on what you mean by
Actually the Bootstrap modal doesn't behave like that
Sure!, if you launch this Bootstrap modal: https://getbootstrap.com/docs/4.3/components/modal/#live-demo you don't get the undesired behaviour I mean, that is you click on the modal, keep clicked, move mouse pointer outside and release, the modal won't close.
Okay, that helps. I don't think this is a bug, but I'll look into what the difference is.
This might help here - https://stackoverflow.com/questions/16152073/prevent-bootstrap-modal-from-disappearing-when-clicking-outside-or-pressing-esca
That's achieved by declaring the backdrop as "static", meaning that clicking on it won't take effect on the modal. But we still want to allow the user to do this.
@tiesont
I think it is a bug. I've found out what's causing the issue to us. If you set a default value to this option:
bootbox.setDefaults({ onEscape: true });
then, as I mentioned, you click anywhere on the modal (except on any button), then drag your mouse, and release outside. Then the modal is closed.
If I remove it, the bootbox will remain open and will only be closed upon clicking on any dismissing button, or in the backdrop, in case we set backdrop: true
@luismartin From what I can tell, the reason this happens is because the target of the click is considered (by the browser) to be element on which the click ended. So, if you mouse-down over the modal but release (mouse-up) over the backdrop, the backdrop is considered the target. That triggers our code which calls dialog.modal('hide').
This has me curious as to whether we can simplify this by always appending the data attributes to trigger a static backdrop unless the backdrop: true option is set. Then we'd inherit Bootstrap's functionality rather than trying to handle this on our own.
It'd be helpful if @makeusabrew could explain why we handle this like we do - JavaScript is not my best language, so I'm sure I'm missing something.
@tarlepp Interestingly enough, if I remove the code starting at https://github.com/makeusabrew/bootbox/blob/master/bootbox.js#L440 , we get the default Bootstrap behavior, and stuff seems to still work correctly. I think that code is an attempt to handle the markup differences between BS3 and BS4+ - what's your feelings on dropping BS3 support for v6, assuming we roll out my updates? That would simplify some other code, like building the modal header, as well.
FWIW, I think this more or less explains what's happening:
If the button is pressed on one element and the pointer is moved outside the element before the button is released, the event is fired on the most specific ancestor element that contained both elements.
See: Element: click event on MDN.
I'll need to look into what BS is doing to handle this, and if our handler can be adjusted to function the same.
@luismartin v6 handles this correctly (I think). If you can, check out the most recent update to the v6-wip branch and let me know if that matches your expectation.
Closed in #820