Multiple modals overlay
Something shorter version based off Yermo Lamers' suggestion, this seems to work alright. Even with basic animations like fade in/out and even crazy batman newspaper rotate. http://jsfiddle.net/ketwaroo/mXy3E/
$('.modal').on('show.bs.modal', function(event) {
var idx = $('.modal:visible').length;
$(this).css('z-index', 1040 + (10 * idx));
});
$('.modal').on('shown.bs.modal', function(event) {
var idx = ($('.modal:visible').length) -1; // raise backdrop after animation.
$('.modal-backdrop').not('.stacked').css('z-index', 1039 + (10 * idx));
$('.modal-backdrop').not('.stacked').addClass('stacked');
});
I realize an answer has been accepted, but I strongly suggest not hacking bootstrap to fix this.
You can pretty easily achieve the same effect by hooking the shown.bs.modal and hidden.bs.modal event handlers and adjusting the z-index there.
Here's a working example
A bit more info is available here.
This solution works automatically with arbitrarily deeply stacks modals.
The script source code:
$(document).ready(function() {
$('.modal').on('hidden.bs.modal', function(event) {
$(this).removeClass( 'fv-modal-stack' );
$('body').data( 'fv_open_modals', $('body').data( 'fv_open_modals' ) - 1 );
});
$('.modal').on('shown.bs.modal', function (event) {
// keep track of the number of open modals
if ( typeof( $('body').data( 'fv_open_modals' ) ) == 'undefined' ) {
$('body').data( 'fv_open_modals', 0 );
}
// if the z-index of this modal has been set, ignore.
if ($(this).hasClass('fv-modal-stack')) {
return;
}
$(this).addClass('fv-modal-stack');
$('body').data('fv_open_modals', $('body').data('fv_open_modals' ) + 1 );
$(this).css('z-index', 1040 + (10 * $('body').data('fv_open_modals' )));
$('.modal-backdrop').not('.fv-modal-stack').css('z-index', 1039 + (10 * $('body').data('fv_open_modals')));
$('.modal-backdrop').not('fv-modal-stack').addClass('fv-modal-stack');
});
});
Solution inspired by the answers of @YermoLamers & @Ketwaroo.
Backdrop z-index fix
This solution uses a setTimeout
because the .modal-backdrop
isn't created when the event show.bs.modal
is triggered.
$(document).on('show.bs.modal', '.modal', function() {
const zIndex = 1040 + 10 * $('.modal:visible').length;
$(this).css('z-index', zIndex);
setTimeout(() => $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack'));
});
- This works for every
.modal
created on the page (even dynamic modals) - The backdrop instantly overlays the previous modal
Example jsfiddle
z-index
If you don't like the hardcoded z-index for any reason you can calculate the highest z-index on the page like this:
const zIndex = 10 +
Math.max(...Array.from(document.querySelectorAll('*')).map((el) => +el.style.zIndex));
Scrollbar fix
If you have a modal on your page that exceeds the browser height, then you can't scroll in it when closing an second modal. To fix this add:
$(document).on('hidden.bs.modal', '.modal',
() => $('.modal:visible').length && $(document.body).addClass('modal-open'));
Versions
This solution is tested with bootstrap 3.1.0 - 3.3.5
Combining A1rPun's answer with the suggestion by StriplingWarrior, I came up with this:
$(document).on({
'show.bs.modal': function () {
var zIndex = 1040 + (10 * $('.modal:visible').length);
$(this).css('z-index', zIndex);
setTimeout(function() {
$('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
}, 0);
},
'hidden.bs.modal': function() {
if ($('.modal:visible').length > 0) {
// restore the modal-open class to the body element, so that scrolling works
// properly after de-stacking a modal.
setTimeout(function() {
$(document.body).addClass('modal-open');
}, 0);
}
}
}, '.modal');
Works even for dynamic modals added after the fact, and removes the second-scrollbar issue. The most notable thing that I found this useful for was integrating forms inside modals with validation feedback from Bootbox alerts, since those use dynamic modals and thus require you to bind the event to document rather than to .modal, since that only attaches it to existing modals.
Fiddle here.