The challenge I'm facing involves implementing a custom Click Outside Directive for closing modal dialogs, notifications, popovers, and other 'popups' triggered by various actions. One specific issue is that when using the directive with popups opened via mouseover event, it requires two clicks to close, whereas popups opened by clicking a button only need one click to dismiss.
For reference, here is an example on Plunker demonstrating this issue.
Below is the code snippet for the directive:
@Directive({
selector: '[clickOutside]'
})
export class ClickOutsideDirective {
@Output('clickOutside') clickOutsideEvent = new EventEmitter();
private globalClick: Subscription;
constructor(private elRef: ElementRef) { }
ngOnInit() {
this.globalClick = Observable
.fromEvent(document, 'click')
.skip(1)
.subscribe((event: MouseEvent) => {
this.clicked(event);
});
}
ngOnDestroy() {
this.globalClick.unsubscribe();
}
private clicked(event: MouseEvent) {
let clickedInside = this.elRef.nativeElement.contains(event.target);
if (!clickedInside) {
this.clickOutsideEvent.emit();
}
}
}
In the ngOnInit() method, an observable is set up to detect clicks on the document and trigger the clicked() function to validate if the click was outside the element. It uses a skip operator to filter out the first event which is not needed within the directive. However, this workaround causes the requirement of two clicks to close a popup generated through methods other than a direct click (as seen in the Mouse Over example on Plunker).
I am looking for a more elegant, simplified solution to address this problem without resorting to 'hacky' methods like stopping event propagation or introducing additional flags. Any suggestions would be greatly appreciated!