Hi,
because of this lines (modal.js 160-162)
if (this._isTransitioning || !this._isShown) {
return;
}
if you invoke modal('hide') before it has ended the show animation it won't hide.
I wasn't able to understand if this was a design choice or some bug preventing, I tested it removing the return and it hasn't shown any problem, the modal hides before the animation has ended.
I was updating my application to 4 beta and noticed that most of the modals weren't closing anymore at the end of a loading.
Regards
@maestroosram why would you show the modal and then hide it again before it is shown? Why not just don't show the modal in the first place?
@Ruffio I often use modals to show status messages, for example during an ajax call: in this case I show a modal with an .alert-info message "Loading..." and then at the end of the call I hide the modal. If the call is too fast the ajax callback will call the modal hide before the modal is totally shown and it won't hide anymore.
I quickly resolved this for myself because I don't call the modal('hide') directly but I use a mask method:
$(this).on('shown.bs.modal', function() {
$(this).modal('hide');
}).modal('hide');
but in general I thought this could happen to more users so I opened the issue.
My suggestion...
Having a modal appear and disappear, even if the ajax response is too fast makes for a confusing user experience. It would be suitable, in my opinion, to allow the modal to open, and provide some status indication that the loading was successful in addition to adding some timing or a manual way out of the modal. Therefore any hide attempt should be suppressed until the AJAX completes in some way, shape, or form.
@maestroosram, big thanks for solution!
@maestroosram your solution works great for most of the cases. But, there is one drawback: if the modal was closed after modal is shown (which means not using the mask, only .modal('hide') part), the event listener (mask) will be already set. Then, in the next modal('show'), it'll close the modal immediately.
Maybe we should also unbind '.shown.bs.modal' on '.hidden.bs.modal'.
For me, it's not an issue or a bug here, it's a choice we made, it's written everywhere in our documentation our methods are asynchronous (example) so you have to listen to our events.
BTW if you want to cancel an event, we have different state of events for example: show.bs.modal and shown.bs.modal.
When shown.bs.modal is triggered your modal is fully shown but when show.bs.modal is triggered your modal will be shown, so you can preventDefault this event.
Example:
var $myModal = $('#myModal')
$myModal.on('show.bs.modal', function (event) {
event.preventDefault();
// your modal won't show
})
Most helpful comment
@Ruffio I often use modals to show status messages, for example during an ajax call: in this case I show a modal with an
.alert-infomessage "Loading..." and then at the end of the call I hide the modal. If the call is too fast the ajax callback will call the modal hide before the modal is totally shown and it won't hide anymore.I quickly resolved this for myself because I don't call the
modal('hide')directly but I use a mask method:$(this).on('shown.bs.modal', function() { $(this).modal('hide'); }).modal('hide');but in general I thought this could happen to more users so I opened the issue.