Popper.js: How to close popup when clicking outside
Asked Answered
C

4

18

I'm using Popper.js to show a popup elment having the class .js-share-cf-popover when clicking elements with class .js-share-cf-btn.

But I want the popup to close only when I click outside of it. Here my actual code that show the popup:

var reference = $('.js-share-cf-btn');
var popover = $('.js-share-cf-popover');
popover.hide();

$(document).on('click', reference, function(e) {
  e.preventDefault();

  popover.show();

  var popper = new Popper(reference, popover, {
    placement: 'top',
  });
});

I found something here but I can't get it works

Here My jsfiddle

Coatbridge answered 4/4, 2018 at 9:27 Comment(2)
Can you provide a jsfiddle ? It ll be easier to help youSteep
Hi @QuentinRoger jsfiddle added in my questionCoatbridge
C
11

You can achieve this, by removing event delegation and checking the target on event click by using the .is(), (compare e.target if it equals to the referencing button, otherwise hide the popup)

See fiddle

Added snippet as your code :

also made change in the Popper instance you should pass the current click js-share-cf-btn so the $(e.target) element

$(function() {
  var reference = $('.js-share-cf-btn');
  var popover = $('.js-share-cf-popover');
  popover.hide();

  $(document).on('click touchend', function(e) {
    var target = $(e.target);
    // ne need to reshow and recreate popper when click over popup so return;
    if(target.is(popover)) return;
    if (target.is(reference)) {
      e.preventDefault();

      popover.show();

      var popper = new Popper(target, popover, {
        placement: 'top',
      });
    }else {
      popover.hide();
    }
  });

});
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

.section {
  background: #fff;
  padding: 20px;
  font-size: 25px;
  text-align: center;
  transition: all 0.2s;
  margin: 0 auto;
  width: 300px;
  margin-bottom: 20px;
}

.share-popover {
  background: red;
  color: white;
  padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<div class="section">
  <p>Section 1</p>
  <a href="#" class="js-share-cf-btn">This is the trigger</a>
</div>

<div class="section">
  <p>Section 2</p>
  <a href="#" class="js-share-cf-btn">This is the trigger</a>
</div>

<div class="section">
  <p>Section 3</p>
  <a href="#" class="js-share-cf-btn">This is the trigger</a>
</div>

<div class="share-popover js-share-cf-popover">
  This is the popup
</div>
Chemo answered 4/4, 2018 at 9:44 Comment(4)
Hi, when I click inside the popup it closes. I want it close only when clicking outside it.Coatbridge
@FredK added fiddle and snippet as you discribed , jsfiddle.net/xpvt214o/44982 Does it work ?Chemo
You could replace click event with click touch for covering also mobile devices.Coatbridge
Or maybe click touchendCoatbridge
S
3

Something like this should do the trick (by checking the target when you are clicking somewhere):

$(function() {
  var ref = $('.js-share-cf-btn');
  var popover = $('.js-share-cf-popover');
  popover.hide();

  $(document).on('click', function(e) {
    var target = $(e.target);
    if (target.is(ref) || target.is(popover) ) {
      e.preventDefault();
      popover.show();
      var popper = new Popper(ref, popover, {
        placement: 'right',
      });
    }else {
      popover.hide();
    }
  });

});

https://jsfiddle.net/e8aL9tje/

Steep answered 4/4, 2018 at 10:2 Comment(3)
Hi, I have multiple button: when click on a button your code shows the popup for every buttons. Check here: jsfiddle.net/tdo2efrsCoatbridge
Is something like this better ? jsfiddle.net/hovaqnxz Have a great day !Steep
It's an improvement but it remains something strange: click first button then click second button. Result: I get the 2 popups opened, while the first one should be closed.Coatbridge
S
0

For those using React, I created a gist of an HOC that you can attach to any component to close it when clicked outside:

https://gist.github.com/elie222/850bc4adede99650508aba2090cd5da1

Sinaloa answered 24/1, 2019 at 20:44 Comment(0)
B
0

I found a really simple solution to this.

jQuery version

<div class="Popper">
    <div class="stopPropagation">
        <p>Clicking on me won't close the Popper</p>
    </div>
</div>
$('.stopPropagation').on('click touchend', function(e) {
    e.stopPropagation()
})

Since the click event does not propagate up to the Popper, the Popper will not closed when clicked.

React version

<Popper>
    {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
    <div onClick={e => e.stopPropagation()} role="none">
        <p>Clicking on me won't close the Popper</p>
    </div>
</Popper>
Burget answered 11/5, 2021 at 7:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.