I am showing a Bootstrap modal window for loading when performing AJAX calls. I broadcast a \"progress.init\" event when the loading modal should show and a \"progress.finis
If after modal hide, faded background is remained and does not let you click any where you can forcefully remove those by using below piece of code.
first hide your modal div element.
$('modalId').modal('hide');
secondly remove 'modal-open' class from body and '.modal-backdrop' at the end of the page.
$('body').removeClass('modal-open');
$('.modal-backdrop').remove();
The problem is that bootstrap removes the backdrop asynchronously. So when you call hide
and show
quickly after each other, the backdrop isn't removed.
The solution (as you've mentioned) is to wait for the modal to have been hidden completely, using the 'hidden.bs.modal'
event. Use jQuery one to only perform the callback once. I've forked your jsfiddle to show how this would work.
// wait for the backdrop to be removed nicely.
loadingModal.one('hidden.bs.modal', function()
{
loadingModal.modal("show");
//Again simulate 3 seconds
setTimeout(function () {
loadingModal.modal("hide");
}, 3000);
});
// hide for the first time, after binding to the hidden event.
loadingModal.modal("hide");
Looking through the code in Bootstrap:
This is what makes hiding the modal asynchronous:
$.support.transition && this.$element.hasClass('fade') ?
this.$element
.one('bsTransitionEnd', $.proxy(this.hideModal, this))
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
this.hideModal()
This checks whether transitions are supported and the fade
class is included on the modal. When both are true
, it waits for the fade effect to complete, before hiding the modal. This waiting happens again before removing the backdrop.
This is why removing the fade class will make hiding the modal synchronous (no more waiting for CSS fade effect to complete) and why the solution by reznic works.
This check determines whether to add or remove the backdrop. isShown = true is performed synchronously. When you call hide
and show
quickly after each other, isShown
becomes true
and the check adds a backdrop, instead of removing the previous one, creating the problem you're having.
just remove class 'fade' from modal
Be carful adding {data-dismiss="modal"} as mentioned in the second answer. When working with Angulars ng-commit using a controller-scope-defined function the data-dismiss will be executed first and controller-scope-defined function is never called. I spend an hour to figure this out.
I got the same problem, the solution is add the property
data-dismiss="modal"
to the button you are going to click.
This is what worked for me -
When the hidden.bs.modal
event is fired, jQuery
's .remove()
function can remove the element that has .modal-backdrop
class. So each time the modal is closed, the modal-backdrop will be removed.
//setting callback function for 'hidden.bs.modal' event
$('#modal').on('hidden.bs.modal', function(){
//remove the backdrop
$('.modal-backdrop').remove();
})
Good Luck.