Detect click outside Angular component

listen for click outside div angular
angular hostlistener
close popover on click outside angular 4
close popover on click outside angular 2
close datepicker when clicked outside angular 2
ionic click outside element
close dropdown on click angular
angular 7 click event on div

How can I detect clicks outside a component in Angular?

import { Component, ElementRef, HostListener, Input } from '@angular/core';

@Component({
  selector: 'selector',
  template: `
    <div>
      {{text}}
    </div>
  `
})
export class AnotherComponent {
  public text: String;

  @HostListener('document:click', ['$event'])
  clickout(event) {
    if(this.eRef.nativeElement.contains(event.target)) {
      this.text = "clicked inside";
    } else {
      this.text = "clicked outside";
    }
  }

  constructor(private eRef: ElementRef) {
    this.text = 'no clicks yet';
  }
}

A working example - click here

Here is the link to the working demo: Stackblitz Demo. I would do this by using the Angular recommended approach which is also easy to  An outside click is a way to know if the user clicks everything BUT a specific component. You may have seen this behavior when opening a dropdown menu or a dropdown list and clicking outside of it

An alternative to AMagyar's answer. This version works when you click on element that gets removed from the DOM with an ngIf.

http://plnkr.co/edit/4mrn4GjM95uvSbQtxrAS?p=preview

  private wasInside = false;
  
  @HostListener('click')
  clickInside() {
    this.text = "clicked inside";
    this.wasInside = true;
  }
  
  @HostListener('document:click')
  clickout() {
    if (!this.wasInside) {
      this.text = "clicked outside";
    }
    this.wasInside = false;
  }

Where close is your function which will be call when user click outside div. import { Component, OnInit, HostListener, ElementRef } from '@angular/core'; . Then you could detect clicks on that element and close the dropdown when it is  Detecting clicks on a component is easy in Angular 2: Just use the (click) event binding, pass a function from the component’s instance and you are done. However, if you need to detect clicks outside of your component, things are getting tricky. You will usually need this for custom implementations of drop-down lists, context menus, pop-ups or widgets.

Binding to document click through @Hostlistener is costly. It can and will have a visible performance impact if you overuse(for example, when building a custom dropdown component and you have multiple instances created in a form).

I suggest adding a @Hostlistener() to the document click event only once inside your main app component. The event should push the value of the clicked target element inside a public subject stored in a global utility service.

@Component({
  selector: 'app-root',
  template: '<router-outlet></router-outlet>'
})
export class AppComponent {

  constructor(private utilitiesService: UtilitiesService) {}

  @HostListener('document:click', ['$event'])
  documentClick(event: any): void {
    this.utilitiesService.documentClickedTarget.next(event.target)
  }
}

@Injectable({ providedIn: 'root' })
export class UtilitiesService {
   documentClickedTarget: Subject<HTMLElement> = new Subject<HTMLElement>()
}

Whoever is interested for the clicked target element should subscribe to the public subject of our utilities service and unsubscribe when the component is destroyed.

export class AnotherComponent implements OnInit {

  @ViewChild('somePopup', { read: ElementRef, static: false }) somePopup: ElementRef

  constructor(private utilitiesService: UtilitiesService) { }

  ngOnInit() {
      this.utilitiesService.documentClickedTarget
           .subscribe(target => this.documentClickListener(target))
  }

  documentClickListener(target: any): void {
     if (this.somePopup.nativeElement.contains(target))
        // Clicked inside  
     else
        // Clicked outside
  }

Angular 2: A Simple Click Outside Directive. Detecting clicks on a component is easy in Angular 2: Just use the (click) event binding, pass a function from the component's instance and you are done. I'm looking for a way to detect if a click event happened outside of a component, as described in this article. jQuery closest() is used to see if the the target from a click event has the dom element as one of its parents. If there is a match the click event belongs to one of the children and is thus not considered to be outside of the component.

Above mentioned answers are correct but what if you are doing a heavy process after losing the focus from the relevant component. For that, I came with a solution with two flags where the focus out event process will only take place when losing the focus from relevant component only.

isFocusInsideComponent = false;
isComponentClicked = false;

@HostListener('click')
clickInside() {
    this.isFocusInsideComponent = true;
    this.isComponentClicked = true;
}

@HostListener('document:click')
clickout() {
    if (!this.isFocusInsideComponent && this.isComponentClicked) {
        // do the heavy process

        this.isComponentClicked = false;
    }
    this.isFocusInsideComponent = false;
}

Hope this will help you. Correct me If have missed anything.

Angular directive for handling click events outside an element. Like binding to a regular click event in a template, you can do something like  An angular directive to detect a click outside of an elements scope, great for clicking outside of slide in and drop down menus amongst other things

You can useclickOutside() method from https://www.npmjs.com/package/ng-click-outside package

Check if the click was outside the element went a step further and added document as our target before the click event name: document:click. Handle clicks outside of React components Sometimes it’s useful to detect clicks outside of a React component to alter its state. A common use case could be a popover which should close if clicked outside of it.

having clicked outside a particular Angular Component or DOM element In the above, we simply listen for the document:click event, which  I upgraded my Angular from 4 to 6, and consequently had a problem with my click-off policy, it stopped working on all components. my directive: import { Directive, Output, EventEmitter, ElementRef,

dropdown.component'; @Component({ selector: 'my-app', template: ` <div DOCTYPE html> <html> <head> <title>Angular 2 Click Outside</title> <meta  To detect a click outside an element we must add a listener on the whole document element. Then the main loop goes up the DOM from the clicked target element to find whether an ancestor of the clicked element belongs to the flyout container.

DOCTYPE html> <html> <head> <title>angular2 playground</title> <link This directive is for detecting clicks outside of a DOM element where the directive is  angular-click-outside. An Angular directive to detect a click outside of an elements scope. Great for closing dialogues, drawers and off screen menu's etc. Recent changes. Shortened Bower description to remove Bower warning on install (thanks @jcubic) Thanks to @Lorelei for the pull request to pass the event back in the callback function

Comments
  • See also stackoverflow.com/questions/35527456/…
  • This doesn't work when there is an element controlled by an ngIf inside the trigger element, since the ngIf removing the element from the DOM happens before the click event: plnkr.co/edit/spctsLxkFCxNqLtfzE5q?p=preview
  • does it work on a component that created dynamiclly via : const factory = this.resolver.resolveComponentFactory(MyComponent); const elem = this.vcr.createComponent(factory);
  • A nice article on this topic: christianliebel.com/2016/05/…
  • This works perfectly with ngif or dynamic updates as well
  • This is awesome
  • Great solution, works flawless!!
  • I think that this one should become the accepted answer as it allows for many optimizations: like in this example