1

I have a button, which opens/displays a modal div which it is clicked. Then, I want this div to hide when the user clicks anywhere in the window outside the div. So based on the code in this SO answer, I wrote the following SSCCE.

But it is NOT working. Once the modal is displayed, clicking outside it does not hide it. Nothing happens when I click outside the modal.

Where am I going wrong? How do I fix it?

Note: I have seen other questions dealing with the same requirement. I found the answered I have linked the best of all, and I tried it. The question is that why is This code not working?

$("button#open-modal-button").click(function() {
  $(".modal").show();
 });



$(document).mouseup(function(event) {
 var modalContainer = $(".modal");

  if (    ( !(modalContainer.is(event.target)) // if the target of the click is Not the modalContainer...
    && (modalContainer.has(event.target).length === 0)  )    ) {// nor a descendant of the modalContainer

   modalContainer.hide();
  }

});
.modal {
 width:100%;
 height:100%;
 background-color:rgba(0,0,0,0.4);
 position:fixed;
 z-index:1;
 display:none;
 left:0;
 top:0;
}

.modal-content {
 margin:5% auto;
 background-color:#fefefe;
 padding:20px;
 border:1px solid #888;
 width:40%;
 height:70vh;
 overflow:auto;
}

body {
 box-shading:border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button id="open-modal-button">Open Modal</button>

<div class="modal">
 <div class="modal-content">
  <div class="modal-header">The header</div>
  <div class="modal-content">
    Some Content
  </div>
 </div>
</div>
Community
  • 1
  • 1
Shy
  • 542
  • 8
  • 20

5 Answers5

3

It's because you have a overlay over the whole site. This shadow overlay has the class modal.

So, you check if the user clicks NOT on modal but your shadow is the modal. Change this and everything will work.

Look at this example where I changed the selector.

$("button#open-modal-button").click(function() {
  $(".modal").show();
});

$(document).mouseup(function(event) {
  var modalContainer = $(".modal");
  var modal = $(".modal-content"); // This is what I've added.

  if ((!(modal.is(event.target)) && (modal.has(event.target).length === 0)) && $(modalContainer).is(":visible")) {
    modalContainer.hide();
  }
});
.modal {
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.4);
  position: fixed;
  z-index: 1;
  display: none;
  left: 0;
  top: 0;
}
.modal-content {
  margin: 5% auto;
  background-color: #fefefe;
  padding: 20px;
  border: 1px solid #888;
  width: 40%;
  height: 70vh;
  overflow: auto;
}
body {
  box-shading: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button id="open-modal-button">Open Modal</button>

<div class="modal">
  <div class="modal-content">
    <div class="modal-header">The header</div>
    <div class="modal-content">
      Some Content
    </div>
  </div>
</div>

EDIT:

I edited my answer and added && $(modalContainer).is(":visible") to the if. Now it will only run into this if the modal is visible.

Patrick Mlr
  • 2,955
  • 2
  • 16
  • 25
  • Sorry to say but I think this is a bad solution. Especially using `$(document).mouseup(function(event) {` which in this case will only be used to close the open modal window. Now this will trigger always if you click somewhere even if the modal is not even open. See here https://jsfiddle.net/qofn4a1d/ and just click somewhere. – caramba Nov 30 '16 at 07:25
1

You where almost there

With this line you are doing something on every mouse up:

    $(document).mouseup(function(event) {

So always a user clicks somewhere on your website he will enter the function. Even if the modal window is not open! Which is not what you want. You just want to close the modal window if click is on .modal but not on one of it's children...

try like so:

$("button#open-modal-button").click(function() {
  $(".modal").show();
 });



$(document).on('click', '.modal', function(event) {
  
    if('modal' !== event.target.className) {
        return;
    }
  
    $(this).hide();

});
.modal {
 width:100%;
 height:100%;
 background-color:rgba(0,0,0,0.4);
 position:fixed;
 z-index:1;
 display:none;
 left:0;
 top:0;
}

.modal-content {
 margin:5% auto;
 background-color:#fefefe;
 padding:20px;
 border:1px solid #888;
 width:40%;
 height:70vh;
 overflow:auto;
}

body {
 box-shading:border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button id="open-modal-button">Open Modal</button>

<div class="modal">
 <div class="modal-content">
  <div class="modal-header">The header</div>
  <div class="modal-content">
    Some Content
  </div>
 </div>
</div>
caramba
  • 21,963
  • 19
  • 86
  • 127
1

Hi you can try with following code...

var _isModalOpen=false;

$("button#open-modal-button").click(function() {
        $(window).off("click",onWindowClick).on("click",onWindowClick);
        $(".modal").show();
        _isModalOpen = true;
    });

function onWindowClick(e)
{
  var modalContainer = $(".modal")[0];
  if(_isModalOpen && e.target != modalContainer)
  {
       $(modalContainer).hide();
       $(window).off("click",onWindowClick);
      _isModalOpen = false;
  }
}
spankajd
  • 934
  • 7
  • 13
1

You can simply have one event for the modal-content to stop the event bubbling and another one for the document to hide the modal as below.

$('.modal-content').mouseup(function(event) {
      event.stopPropagation();
    });


    $(document).mouseup(function(event) {
        $(".modal").hide();
    });

Working snippet:

$("button#open-modal-button").click(function() {
  $(".modal").show();
});

$('.modal-content').mouseup(function(event) {
  event.stopPropagation();
});


$(document).mouseup(function(event) {
 $(".modal").hide();
});
.modal {
 width:100%;
 height:100%;
 background-color:rgba(0,0,0,0.4);
 position:fixed;
 z-index:1;
 display:none;
 left:0;
 top:0;
}

.modal-content {
 margin:5% auto;
 background-color:#fefefe;
 padding:20px;
 border:1px solid #888;
 width:40%;
 height:70vh;
 overflow:auto;
}

body {
 box-shading:border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button id="open-modal-button">Open Modal</button>

<div class="modal">
 <div class="modal-content">
  <div class="modal-header">The header</div>
  <div class="modal-content">
    Some Content
  </div>
 </div>
</div>
Aruna
  • 11,959
  • 3
  • 28
  • 42
-2

You can use this function:

$("button#open-modal-button").click(function() {
    $("#myModal").modal({backdrop: true});
});
Luka Kerr
  • 4,161
  • 7
  • 39
  • 50
dhanaraj
  • 1
  • 2