Question

I have this issue where I need to open multiple modals. The good thing is that before I open a new modal, the existing one can be closed. When a modal is opened normally I get a class applied to the body called "modal-open" which applies overflow: hidden to the body.

I created this script:

var login = function () {

    var handleRegister = function () {

        $("a").click(function (e) {
            var target = $(this).data("target");

            if (target) {
                var visible = $(target).is(":visible");

                if (!visible) { 
                    $('.modal').each(function () {
                        $(this).modal('hide'); // hide existing modals
                    });

                    $(target).modal('show');
                }

                e.preventDefault();
            }
        });
    }

    return {
        init: function () {
            handleRegister();
        }
    }
}();

As you can see, I loop through any existing modals and close them (I assume this calls the hidden.bs.modal and removes the modal-open class from the body) and after these have run I call the show method on my target. The problem is the modal-open class is not applied to the body.

I tried adding $("body").addClass("modal-open") after the show call, but the class is not added.

Has someone come across this before?

Was it helpful?

Solution

I fixed this by hooking into the modal hidden/shown events. My amended script looks like this:

    var login = function () {

        var handleRegister = function () {

            $("a, button").click(function (e) {
                var target = $(this).data("target");
                var type = $(this).data("type");

                if (target && type) {
                    var visible = $(target).is(":visible");

                    if (!visible) {                    
                        var available_height = $(window).height() - $('.topbar').outerHeight();
                        var content = $('.modal-content', target);
                        content.height(available_height);

                        $('.modal').each(function () {
                            $(this).modal('hide'); // hide all existing modals
                        });

                        $(target).modal('show');
                    }

                    e.preventDefault();
                }
            });

            $('.modal').on('hidden.bs.modal', function (e) {
                $("body").removeClass("modal-open");
            });

            $('.modal').on('shown.bs.modal', function (e) {
                $("body").addClass("modal-open");
            });
        }

        return {
            init: function () {
                handleRegister();
            }
        }
    }();

I am unsure why this works as I would expect that this is what would be happening in the modal script anyway. But it works, so hey ho.

OTHER TIPS

Here is my solution:


Before you open your second modal:

hasAlreadyModalOpen = $("BODY").hasClass("modal-open");
mySecondModal.modal("show");

mySecondModal.on('hidden.bs.modal', function (e) {
    if (hasAlreadyModalOpen) {
        $("body").addClass("modal-open");
    }
});

A very old question but a simplified answer as this is high on search results and it is still an issue. Adding an additional class to any secondary modals e.g. sub-modal and then hooking into their hidden event will mitigate this simply.

$(document).on("hidden.bs.modal",".sub-modal.modal", function () {
    $("body").addClass("modal-open");
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top