I'm working on directive that should close dropdown after click outside. The element that has directive also has*ngIf
and is not present on the page at the time of click, but directive is still firing the event - so the dropdown is never opened as showList
becomes false
immediatelly after (click)="showList = true"
fired. How do I avoid this?
import { Directive, HostListener, ElementRef, EventEmitter, Inject, PLATFORM_ID, Output, Input, OnInit, Renderer2, AfterContentInit } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
@Directive({
selector: '[clickOutside]'
})
export class ClickOutsideDirective implements AfterContentInit {
ngAfterContentInit(): void {
this.contentInitialized = true;
}
@Input("clickOutside") config: any = {};
@Output() clickOutside: EventEmitter<any> = new EventEmitter();
private isBrowser: boolean = false;
private isIE11: boolean = false;
private contentInitialized: boolean = false;
constructor(private renderer: Renderer2, private _el: ElementRef, @Inject(PLATFORM_ID) private platformId: any) {
this.isBrowser = isPlatformBrowser(platformId);
this.isIE11 = this.isBrowser && !!(window as any).MSInputMethodContext && !!(document as any).documentMode;
}
@HostListener('document:click', ['$event'])
public onClick(event) {
console.log("CLICKED");
if (this.contentInitialized && !(this._el.nativeElement.contains(event.target) || (event.target == window.document.querySelector(this.config.excludeLocator)))) {
this.clickOutside.emit(event);
}
}
@HostListener('document:keyup', ['$event'])
private onKeyup(event) {
if (event.keyCode == 27) {
this.clickOutside.emit(event);
}
}
}
<div class="menu-trigger" (click)="showList = true"></div>
<ul class="list" *ngIf="showList" (clickOutside)="showGiftList = false">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
To avoid Parent event running you need to stop it from child element, you can do it by
$event.stopPropagation();
The
event.stopPropagation()
method stops the bubbling of an event to parent elements, preventing any parent event handlers from being executed.
If you want to learn some basics and advance more HTML EVENTS you can check this out.