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

Bourbia Brahim
  • 14,459
  • 4
  • 39
  • 52
Fred K
  • 13,249
  • 14
  • 78
  • 103

4 Answers4

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>
Bourbia Brahim
  • 14,459
  • 4
  • 39
  • 52
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/

Quentin Roger
  • 6,410
  • 2
  • 23
  • 36
  • Hi, I have multiple button: when click on a button your code shows the popup for every buttons. Check here: https://jsfiddle.net/tdo2efrs/ – Fred K Apr 04 '18 at 11:10
  • Is something like this better ? https://jsfiddle.net/hovaqnxz/ Have a great day ! – Quentin Roger Apr 04 '18 at 11:53
  • 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. – Fred K Apr 04 '18 at 14:56
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

Eliezer Steinbock
  • 4,728
  • 5
  • 31
  • 43
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>
Daniel Tonon
  • 9,261
  • 5
  • 61
  • 64