Jack H
Jack H

Reputation: 344

How to make modal close on click outside

I have used this JavaScript below:

$('body').click(function() {
  if (!$(this.target).is('#popUpForm')) {
    $(".modalDialog").hide();
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
  <div id="openModal" class="modalDialog">
    <div class="modalClose">
      <a href="#close" title="Close" class="close-circle" style="color:white; text-decoration:none; font-size:14px;"></a>
      <div id="signup-header">
        <h4>Request a brochure, with a free demo</h4>
        <h5>Please Fill in the form below: </h5>
      </div>

      <form id="popUpForm" class="tryMeForm" name="" onsubmit="return formCheck(this);" method="post" action="">
        <div class="InputGroup">
          <input type="text" name="name" id="name" value="" placeholder="First Name*" />
        </div>
        <div class="InputGroup">
          <input type="text" name="lastname" id="lastname" value="" placeholder="Last Name*" />
        </div>
        <div class="InputGroup">
          <input type="text" name="Email" id="Email" value="" placeholder="Email Address*" />
        </div>
        <div class="InputGroup">
          <input type="text" name="Phone" id="Phone" value="" placeholder="Phone Number*" />
        </div>
        <div class="InputGroup">
          <textarea name="message" id="message" class="" placeholder="How we can help?"></textarea>
        </div>
        <div class="submit">
          <input class="button_submit1 button-primary button1" type="submit" value="Submit" />
        </div>

      </form>
    </div>
  </div>
</body>

This allows me to close the modal when clicking outside of it. However, it closes even when I click inside as well. How can I make it close only on outside and the close button, but not inside, so the users can still enter their details?

Upvotes: 27

Views: 232616

Answers (14)

Jetro Bernardo
Jetro Bernardo

Reputation: 67

with Jquery, hide the element that has the class 'hider'.

$(document).mouseup(function(e){
  var container = $(".hider");
  if(!container.is(e.target) && container.has(e.target).length === 0){ container.slideUp(80); }
});

Upvotes: 0

Arif Maksum
Arif Maksum

Reputation: 141

Simple code you can add data-backdrop="true" on div modal . its work for me

<div class="modalDialog" id="openModal" data-backdrop="true">

Upvotes: 0

heyyy
heyyy

Reputation: 83

This worked for my dropup menu that I was coding outside of the bootstrap framework. Basically, if a click was outside the enclosing div, then close the menu. Use the Node.contains method.

function checkParent(parent, child) {
    if (parent.contains(child))
        return true;
        return false;
}

credit to geeksforgeeks

Upvotes: 1

user966939
user966939

Reputation: 719

The best solution I've found is to put the "outside" (the backdrop/background) inside of the wrapper element for the modal parts.

HTML:

<div id="modal-root" style="display: none;">
  <div id="modal-bg" onclick="onClickModalBackdrop(this)"></div>
  <div id="modal">
    <div id="modal-close-btn" onclick="onClickModalCloseBtn(this)">X</div>
    <!-- content here -->
  </div>
</div>

CSS:

#modal-root {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

#modal-bg {
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
}

#modal {
  padding: 1em;
  background-color: #e0e0e0;
  position: relative;
}

#modal-close-btn {
  position: absolute;
  background-color: #d1d1d1;
  right: 1em;
  top: 1em;
  cursor: pointer;
  font-size: 16px;
  font-weight: bold;
  border: 1px solid #a8a8a8;
  color: #959595;
  padding: 4px 8px;
}

#modal-close-btn:hover {
  color: #757575;
  background-color: #c0c0c0;
  border-color: #959595;
}

JavaScript:

function showModal() {
  document.getElementById("modal-root").style.display = '';
}

function onClickModalBackdrop(e) {
  e.parentNode.style.display = 'none';
}

function onClickModalCloseBtn(e) {
  e.parentNode.parentNode.style.display = 'none';
}

showModal();

Upvotes: 0

felixkpt
felixkpt

Reputation: 148

Sample markup:

<html>
<head>
</head>
<body>
  <div class="media-modal-wrapper">
    <div class="media-modal">Modal content here...</div>
  </div>
</body>
</html>

A very helpful solution to this problem:

    var wrapper = document.getElementsByClassName('media-modal-wrapper')[0];
    wrapper.addEventListener('click', function (event) {
    const self = event.target.closest('.media-modal');
    if (!self) {
        wrapper.classList.add('hidden')
    }
})

Upvotes: 2

MD.Moon Kabir
MD.Moon Kabir

Reputation: 21

$("#bootstrap_modal_id").modal({
    backdrop: true,
});

Upvotes: -1

Velibor
Velibor

Reputation: 1

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

Upvotes: 0

Usman Mahmood
Usman Mahmood

Reputation: 89

Simple:

var images_modal = document.getElementById('images-model-div');

var videos_modal = document.getElementById('video-model-div');

// When the user clicks anywhere outside of the modal, close it

window.onclick = function(event) {

   if (event.target == images_modal) {

      images_modal.style.display = "none";

    }

    if (event.target == videos_modal) {

      videos_modal.style.display = "none";

    }

}

Upvotes: 7

Zakaria Acharki
Zakaria Acharki

Reputation: 67505

Use the parent node #openModal (container) instead of #popUpForm (form) :

$('body').click(function (event) 
{
   if(!$(event.target).closest('#openModal').length && !$(event.target).is('#openModal')) {
     $(".modalDialog").hide();
   }     
});

Upvotes: 27

nbalaguer
nbalaguer

Reputation: 181

Adding to this for future readers.

Another way to dismiss the modal when clicking outside involved taking advantage of the bubbling nature of the javascript events.

In a typical modal HTML structure

<body>
  <div id="root">
    -- Site content here
  </div>
  <div id="modal-root">
    <div class="modal"></div>
  </div>
</body>

clicking on .modal will cause the click event to propagate like this .modal -> #modal-root -> body while clicking outside the modal will only go through #modal-root -> body.

Since we can stop the propagation of click events completely, and if that does not interfere with any other code, we only need to listen for click events in both .modal and #modal-root. A "modal-root" click will dismiss the modal, and a "modal" click will stop propagating the click event so never reaches the "modal-root".

For extra clarity, here's the code working in codepen.io: https://codepen.io/nbalaguer/pen/PVbEjm

Upvotes: 18

Marcela Nakakomi
Marcela Nakakomi

Reputation: 91

This is working for me: I have an image inside of the modal window, so if someone click outside the image (centered):

html code:

<div id="modal_div"><img id="image_in_modal_div" src="image.jpg" /></div>

ccs code:

#modal_div {
        display: none;
          position: fixed; 
        z-index: 1; 
        left: 0;
        top: 0;
        width: 100%; 
        height: 100%; 
        overflow: auto; 
          background-color: transparent;
}

#image_in_modal_div {
       left: 50%;
       top: 30%;
       position: absolute;
}

mixed jquery and javascript code:

$( document ).ready(function() {

    $("#element_that_opens_modal").click(function(){
        $("#modal_div").show();
    });

    window.onclick = function(event) {
       if (event.target.id != "image_in_modal_div") {
          $("#modal_div").hide();
       }
    }

});

Upvotes: 9

Jack H
Jack H

Reputation: 344

This seemed to be the code that worked out for me in the end:

$(document).click(function (e) {
    if ($(e.target).is('#openModal')) {
        $('#openModal').fadeOut(500);
    }

});

$("#modalNo").click(function () {
    $("#openModal").fadeOut(500);


});
$(".close").click(function () {
    $("#openModal").fadeOut(500);
});
$(".close-circle").click(function () {
    $("#openModal").fadeOut(500);
});

Upvotes: 6

Abdullah
Abdullah

Reputation: 998

$('body').on('click', '.modal-open', function(e) {
    
    $('.modal-background, .modal').show();
    e.preventDefault();
})
.on('click', '.modal-close', function(e) {
    
    $('.modal-background, .modal').hide();
    e.preventDefault();
});

if ( !$('.modal-background.modal-close').length ) {
    $('<div/>').addClass('modal-background modal-close').appendTo('body');
}
body {
    background: #ccc;
    overflow-y: scroll;
    padding: 15px;
}

button {
    cursor: pointer;
}

.modal {
    width: 400px;
    margin: 5% auto 0 -200px;
    padding: 10px;
    background: #eee;
    display: none;
    position: absolute;
    left: 50%;
    top: 0;
    z-index: 10;
}

.modal-background {
    background: rgba(0, 0, 0, 0.5);
    /* background: transparent; */
    /* position: absolute; */
    position: fixed;
    z-index: 9; /* .modal[zIndex] - 1 */
    bottom: 0;
    right: 0;
    left: 0;
    top: 0;
    display: none;
}
<p>
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
<button type="button" class="modal-open">Open modal</button>

<div class="modal">
    <p>
        It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
    </p>
    <p>
        <button type="button" onclick="$('.dummy-container').toggle()">Toggle something for testing</button>
    <p>
    <p class="dummy-container" style="display: none;">
        Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
    </p>
    <p>
        <button type="button" class="modal-close">Close modal</button>
    </p>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 2

Ryan
Ryan

Reputation: 14649

This is not the most efficient way, but it will work. The idea is to traverse the tree and check if the parent is the id of the one where you don't want to hide on click anywhere except it.

$(document).on('click', function(e) {    
    var p = e.target;
    while(p) {
        console.log(p);
        if(p.id) {
            if(p.id == 'openModal') {
                return;
            }
        }
        p = p.parentElement;
    }
    $("#openModal").hide();
});

Upvotes: 3

Related Questions