Search code examples
javascriptjquerybootstrap-4bootstrap-modal

How to detect the way Bootstrap modal is closed


I'm attaching handler to the Bootstrap hidden.bs.modal event to detect when the modal is closed, but it can be closed in multiple ways:

  1. Explicitly close it via$('#modal').modal('hide') or $('#modal').modal('toggle');
  2. Clicking on modal's backdrop part (if allowed);
  3. Via data attributes e.g. data-dismiss="modal"

Is there a way to detect which of the options was used? Inside the hidden.bs.modal handler e.target always appears to be div#modal


Solution

  • The thing is that hidden.bs.modal is an event that fires once the modal has been closed. So that is not the click event the user triggered from the close button, the corner X or the overlay...

    That said, you can use the click event to store where the user clicked in a variable and milliseconds after, when the hidden.bs.modal fires, use the variable.

    Demo:

    $(document).ready(function(){
    
      // Variable to be set on click on the modal... Then used when the modal hidden event fires
      var modalClosingMethod = "Programmatically";
    
      // On modal click, determine where the click occurs and set the variable accordingly
      $('#exampleModal').on('click', function (e) {
    
        if ($(e.target).parent().attr("data-dismiss")){
          modalClosingMethod = "by Corner X";
        }
        else if ($(e.target).hasClass("btn-secondary")){
          modalClosingMethod = "by Close Button";
        }
        else{
          modalClosingMethod = "by Background Overlay";
        }
    
        // Restore the variable "default" value
        setTimeout(function(){
          modalClosingMethod = "Programmatically";
        },500);
      });
    
      // Modal hidden event fired
      $('#exampleModal').on('hidden.bs.modal', function () {
        console.log("Modal closed "+modalClosingMethod);
      });
    
      // Closing programmatically example
      $('#exampleModal').modal("show");
      setTimeout(function(){
        $('#exampleModal').modal("hide");
      },1000);
    });
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
    
    <!-- Button trigger modal -->
    <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
      Launch demo modal
    </button>
    
    <!-- Modal -->
    <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
      <div class="modal-dialog" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            ...
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
            <button type="button" class="btn btn-primary">Save changes</button>
          </div>
        </div>
      </div>
    </div>

    CodePen