# Hide a popup on clicking outside the popup area

**URL:** <https://discuss.hotwired.dev/t/hide-a-popup-on-clicking-outside-the-popup-area/67>\
**Category:** General\
**Created:** [February 9, 2018, 7:30am UTC](https://discuss.hotwired.dev/t/hide-a-popup-on-clicking-outside-the-popup-area/67 "2018-02-09T07:30:27Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![arunan](https://avatars.discourse-cdn.com/v4/letter/a/d9b06d/32.png) [@arunan](https://discuss.hotwired.dev/u/arunan)\
**Post date:** [February 9, 2018, 7:30am UTC](https://discuss.hotwired.dev/t/hide-a-popup-on-clicking-outside-the-popup-area/67/1 "2018-02-09T07:30:27Z")

</div>

Not sure how I’d do this with Stimulus:

```
var box = document.querySelector(".box");

// Detect all clicks on the document
document.addEventListener("click", function(event) {
	// If user clicks inside the element, do nothing
	if (event.target.closest(".box")) return;

	// If user clicks outside the element, hide it!
	box.classList.add("js-is-hidden");
});

```

Any suggestions would be appreciated.

Thanks! 🙂

---

<div class="post-metadata">

**Author:** ![meneerprins](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/meneerprins/32/73_2.png) [@meneerprins](https://discuss.hotwired.dev/u/meneerprins)\
**Post date:** [February 9, 2018, 10:38am UTC](https://discuss.hotwired.dev/t/hide-a-popup-on-clicking-outside-the-popup-area/67/2 "2018-02-09T10:38:48Z")

</div>

I have something like this where this.bodyElement is just the body tag and this.closeSidebar() a function that removed classes (in my case it’s a sidebar overlay instead of a modal but does the same thing.

```
_canClose() {
  const outsideClickListener = event => {
    if (!event.target.closest('.form-sidebar')) {
      this.closeSidebar();
      removeClickListener();
    }
  };

  const removeClickListener = () => {
    this.bodyElement.removeEventListener('click', outsideClickListener);
  };

  this.bodyElement.addEventListener('click', outsideClickListener);
}
```

---

<div class="post-metadata">

**Author:** ![arunan](https://avatars.discourse-cdn.com/v4/letter/a/d9b06d/32.png) [@arunan](https://discuss.hotwired.dev/u/arunan)\
**Post date:** [February 9, 2018, 1:34pm UTC](https://discuss.hotwired.dev/t/hide-a-popup-on-clicking-outside-the-popup-area/67/3 "2018-02-09T13:34:05Z")

</div>

I was thinking along similar lines, but was just wondering if there was something achievable with the data-action/targers 😬

---

<div class="post-metadata">

**Author:** ![pascallaliberte](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/pascallaliberte/32/18_2.png) [@pascallaliberte](https://discuss.hotwired.dev/u/pascallaliberte)\
**Post date:** [February 9, 2018, 1:49pm UTC](https://discuss.hotwired.dev/t/hide-a-popup-on-clicking-outside-the-popup-area/67/4 "2018-02-09T13:49:22Z")

</div>

Yep, you can use a `data-action="click@window->controller-name#hide"`, like here:

> <https://github.com/pascallaliberte/stimulus-turbolinks-demo/blob/cd7fb5a04ca330d3fd5ec76ab468359376134986/_includes/header.html#L12>

---

<div class="post-metadata">

**Author:** ![arunan](https://avatars.discourse-cdn.com/v4/letter/a/d9b06d/32.png) [@arunan](https://discuss.hotwired.dev/u/arunan)\
**Post date:** [February 10, 2018, 10:31pm UTC](https://discuss.hotwired.dev/t/hide-a-popup-on-clicking-outside-the-popup-area/67/5 "2018-02-10T22:31:24Z")

</div>

Awesome! 🕶

Thanks for the replies all 😄

---

<div class="post-metadata">

**Author:** ![arunan](https://avatars.discourse-cdn.com/v4/letter/a/d9b06d/32.png) [@arunan](https://discuss.hotwired.dev/u/arunan)\
**Post date:** [February 11, 2018, 10:32pm UTC](https://discuss.hotwired.dev/t/hide-a-popup-on-clicking-outside-the-popup-area/67/6 "2018-02-11T22:32:28Z")

</div>

@pasacallaliberte the only issue seems to be that I can’t click an element inside the dropdown (I have an input) without triggering the _hide_ - any suggestions?

e.g. code is here: [https://codepen.io/askalot/pen/PQmEXL](https://codepen.io/askalot/pen/PQmEXL) - but I am unable to get it to work as the _static target = [‘menu’,‘button’]_ line is throwing an error in CodePen.

---

<div class="post-metadata">

**Author:** ![crispinheneise](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/crispinheneise/32/15_2.png) [@crispinheneise](https://discuss.hotwired.dev/u/crispinheneise)\
**Post date:** [August 17, 2018, 4:58pm UTC](https://discuss.hotwired.dev/t/hide-a-popup-on-clicking-outside-the-popup-area/67/7 "2018-08-17T16:58:11Z")

</div>

@arunan you might be able to do something like this:

```
if (this.element.contains(event.target) == false) {
  this.droptownTarget.classList.add("hidden");
}
```

---

<div class="post-metadata">

**Author:** ![sgromkov](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/sgromkov/32/445_2.png) [@sgromkov](https://discuss.hotwired.dev/u/sgromkov)\
**Post date:** [April 3, 2019, 11:08am UTC](https://discuss.hotwired.dev/t/hide-a-popup-on-clicking-outside-the-popup-area/67/8 "2019-04-03T11:08:33Z")

</div>

Thanks! Your suggestion was useful for me.

When i tried to use few dropdowns, clicks on their buttons prevented hiding of opened popups. So, I’ve done some improvements:

```
import { Controller } from 'stimulus';

export default class extends Controller {
    static targets = ['button', 'popup']

    toggle () {
        // removed event.stopPropagation() to continue the bubbling for others dropdowns
        event.preventDefault();

        if (this.buttonTarget.getAttribute('aria-expanded') == "false") {
            this.show();
        } else {
            this.hide(null);
        }
    }

    show() {
        this.buttonTarget.setAttribute('aria-expanded', 'true');
        this.buttonTarget.classList.add('is-active');
        this.popupTarget.classList.remove('is-hidden');
    }

    hide(event) {
        // changed your solution with crispinheneise's recommendation and added additional check:
        if (event && (this.popupTarget.contains(event.target) || this.buttonTarget.contains(event.target))) {
            event.preventDefault();
            return;
        }

        this.buttonTarget.setAttribute('aria-expanded', 'false');
        this.buttonTarget.classList.remove('is-active');
        this.popupTarget.classList.add('is-hidden');
    }
}
```
