openaire-library/utils/click/click-outside-or-esc.direct...

85 lines
2.2 KiB
TypeScript

import {Directive, OnInit, OnDestroy, Output, EventEmitter, ElementRef, Input} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/delay';
import 'rxjs/add/operator/do';
import {Subscriber} from "rxjs";
@Directive({
selector: '[click-outside-or-esc]'
})
export class ClickOutsideOrEsc implements OnInit, OnDestroy {
private listening: boolean;
private subscriptions: any[] = [];
@Input()
public targetId = null;
@Input()
public escClose = true;
@Input()
public clickClose = true;
@Output('clickOutside') clickOutside: EventEmitter<Object>;
constructor(private _elRef: ElementRef) {
this.listening = false;
this.clickOutside = new EventEmitter();
}
ngOnInit() {
if(typeof document !== 'undefined') {
this.subscriptions.push(Observable
.fromEvent(document, 'click')
.delay(1)
.do(() => {
this.listening = true;
}).subscribe((event: MouseEvent) => {
this.onGlobalClick(event);
}));
this.subscriptions.push(Observable
.fromEvent(document, 'keydown')
.delay(1)
.do(() => {
this.listening = true;
}).subscribe((event: KeyboardEvent) => {
if (event.keyCode === 27 && this.escClose) {
this.clickOutside.emit({
target: (event.target || null),
value: true
});
}
}));
}
}
ngOnDestroy() {
if (this.subscriptions) {
this.subscriptions.forEach((subscription: Subscriber<any>) => {
subscription.unsubscribe();
});
}
this.subscriptions = [];
}
onGlobalClick(event: MouseEvent) {
if (event instanceof MouseEvent && this.listening === true) {
let element: HTMLElement = <HTMLElement>event.target;
while (element) {
if(element.id === this.targetId) {
this.clickOutside.emit({
target: (event.target || null),
value: false
});
return;
}
element = element.parentElement;
}
if(this.clickClose) {
this.clickOutside.emit({
target: (event.target || null),
value: true
});
}
}
}
}