1

I have a web page that makes use of a number of different modals to display information to the user.

These modals are triggered by certain buttons, which usually call $("#id").modal("toggle") to toggle the modal's visibility on. In one particular scenario, I have one modal which displays a second modal through the use of the above stated function. It also hides itself through the use of the same function, so I have an onClick function that does the following.

$("#EditTask").modal("hide");
$("#AddressProspect").modal("show");

The issue is that when the AddressProspect modal is displayed, it seems as though it is not being changed to the active element. The background goes dark, and the modal is displayed correctly. However when I attempt to scroll, the background elements scroll instead, as if the modal hasn't actually been displayed.

I have attempted a number of different approaches. I have used .modal("show") and .modal("hide") to display the modals I need. I have also trieddata-dismiss="modal" within the button of the modal that needs to be hidden. These have all produced the exact same result.

Interestingly, if I go to my console and execute the following commands

$("body").css("overflow-y", "hidden");
$("#AddressProspect").css("overflow-y", "scroll");

The background becomes unscrollable, and the AddressProspect modal becomes scrollable, just as I would expect.

I have around 10 modals being used within my page, and none of them have this problem apart from the one in question. I have posted the code to the two modals mentioned in this post below, with their bodies removed for clarity.

<div class="modal fade bd-example-modal-lg" id="EditTask" tabindex="-1" role="dialog" data-keyboard="false" data-backdrop="static" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel"><span class="Title">Title</span></h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">

                    -snip-

            </div>
            <div class="modal-footer">
                <div style="width: 100%">
                    <button type="button" class="btn btn-warning action-skip-instruction" style="float: left;" data-dismiss="modal">Skip Instruction</button>
                </div>

                <button type="button" class="btn btn-secondary action-close-edit-modal">Close</button>
                <button type="button" id="edit-task-button-defer" class="btn btn-warning edit-task-action" style="display: none;">Defer</button>
                <button type="button" id="edit-task-button-action" class="btn btn-success edit-task-action" data-dismiss="modal">Complete</button>

            </div>
        </div>
    </div>
</div>

<div class="modal fade" id="AddressProspect" tabindex="-1" role="dialog" data-keyboard="false" data-backdrop="static" aria-labelledby="exampleModalLabel" aria-hidden="true">
        <div class="modal-dialog" style="max-width: 600px;" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">New Security Address Prospect</h5>
                </div>

                <div class="modal-body">

                    -snip-

                </div>
                <div class="modal-footer">
                    <div style="width: 100%">
                        <button type="button" class="btn btn-warning prospect-button-clear" style="float: left;">Clear</button>
                    </div>

                    <button type="button" style="float: left;" class="btn btn-danger prospect-button-close" data-dismiss="modal">Close</button>
                    <button type="button" class="btn btn-success prospect-button-update">Update</button>
                </div>
            </div>
        </div>
    </div>
Jake12342134
  • 1,539
  • 1
  • 18
  • 45
  • I feel like I've encountered this before. Do you hide a modal and show another modal with `$('#modal1').modal('hide'); $('#modal2').modal('show') ` everywhere else as well? As in it gets called one after the other? – Iskandar Reza Mar 12 '19 at 18:32
  • Yeah exactly, there's a lot of different transitions between two modals in my code using the functions you mentioned – Jake12342134 Mar 13 '19 at 08:13
  • I dug into a project I'm working on to look for the point I encountered this issue before, and I added this right before calling the code to show the modal: `$(".modal-backdrop").remove();` . What had happened there was the modal backdrop was preventing the modal itself from being the active element because the backdrop got on top of the modal instead of behind. Still have no idea how that happened but this seems to fix it. I don't know if this will help you but it's worth a shot because the backdrop is appended to the body by `bootstrap.min.js` when you run `.modal('show');` – Iskandar Reza Mar 13 '19 at 21:51
  • I'll give this a shot, definitely not something I'd have tried. I'll let you know if it works, thanks! – Jake12342134 Mar 14 '19 at 08:10
  • @IskandarRezaRazali Hello, sorry it's taken me a while to get back to you. I tried your suggestion but unfortunately there is no change in behaviour. One interesting note is that if I execute `$("#EditTask").modal("toggle");` followed by `$("#AddressProspect").modal("toggle");` in the browser console, I get the exact behaviour I require. But when executed programmatically in my .js file they do not work. – Jake12342134 Mar 15 '19 at 11:33
  • Possible duplicate of [Prevent BODY from scrolling when a modal is opened](https://stackoverflow.com/questions/9538868/prevent-body-from-scrolling-when-a-modal-is-opened) – Guybrush Threepwood Jul 29 '19 at 11:14

1 Answers1

2

After a decent amount of time having issues with this problem I have managed to figure out why it is happening and how to fix it.

There are two places I looked for information on this topic:

This Github issue on the Bootstrap repo

The Bootstrap documentation on modal methods

From reading the Github issue we can see that one user notes that the calls to .modal("hide") and .modal("show") are asynchronous, therefore using them in quick succession is invalid. Instead we must wait for the show/hide to complete by listening for the shown or hidden events.

To do this we can use the following function:

$('#myModal').on('hidden.bs.modal', function (e) {
  // do something...
})

By checking for the hidden.bs.modal class to be placed into the modal's classlist we can verify when the hide animation has completely finished. At this point we can then call the show method of the next modal to be displayed, ensuring that all of the background events handled by Bootstrap have finished executing, and ensuring that behaviour is expected.

My previous code goes from being:

$("#EditTask").modal("hide");
$("#AddressProspect").modal("show");

to:

$("#EditTask").modal('toggle');
$("#EditTask").on("hidden.bs.modal", function() {
      $("#AddressProspect").modal('toggle');        
      });

As soon as I tried the new code, the weird issues with scrolling disappeared.

Jake12342134
  • 1,539
  • 1
  • 18
  • 45