DEV Community

Cover image for Angular Directive that detects click outside of its host element
MD ASHRAF
MD ASHRAF

Posted on

Angular Directive that detects click outside of its host element

Approach:

  1. Angular directive needs to listen for click events on the entire document.
  2. Then check if the clicked element is within its host element or not.

click-outside.directive.ts

Image custom directive

Let's break down the code:

@Directive({ selector: '[appClickOutside]' }): This means you'll apply the directive to an HTML element like this: <div appClickOutside>...</div>

@HostListener('document:click', ['$event.target']): This tells Angular to listen for the click event on the entire document object, not just the host element itself. This is crucial for detecting clicks outside.

['$event.target']: This tells Angular to pass the target property of the click event (which is the actual DOM element that was clicked) as an argument to our onClickmethod.

const clickedInside = this.elementRef.nativeElement.contains(targetElement); : This line uses the contains() method of the DOM Node interface. It checks if the targetElement (the element that was clicked) is a descendant of the directive's host element (this.elementRef.nativeElement).

How to Use It:

Define in module:

// src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ClickOutsideDirective } from './click-outside.directive'; // Import your directive

@NgModule({
  declarations: [
    AppComponent,
    ClickOutsideDirective // <---  Declare your directive
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

component.html

<div style="border: 2px solid blue; padding: 20px; margin: 50px;"
  appClickOutside   <-- THIS IS WHERE THE DIRECTIVE IS APPLIED -->
  clickOutside)="onClickedOutside()">  <-- THIS IS WHERE THE COMPONENT LISTENS TO THE DIRECTIVE'S OUTPUT -->
  This is the host element. Click anywhere outside this blue box!
  <button (click)="onButtonClick($event)">Click Me (Inside)</button>
</div>

<p *ngIf="message">{{ message }}</p>
Enter fullscreen mode Exit fullscreen mode

Handling event on click in component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  message: string = '';

  onClickedOutside(): void {
    this.message = 'Clicked outside the box!';
    console.log('Clicked outside the element!');
  }

  onButtonClick(event: Event): void {
    event.stopPropagation(); // Prevent the document click listener from firing immediately
    this.message = 'Button inside clicked!';
    console.log('Button inside clicked!');
  }
}
Enter fullscreen mode Exit fullscreen mode

📌📌 More angular learnings here:

RXJS and Angular Bonding
Angular HTTP integration
XSS Attack and Angular Handling

Top comments (0)