diff --git a/sharedComponents/input/input.component.ts b/sharedComponents/input/input.component.ts index 71436adc..b3498154 100644 --- a/sharedComponents/input/input.component.ts +++ b/sharedComponents/input/input.component.ts @@ -17,6 +17,7 @@ import {HelperFunctions} from "../../utils/HelperFunctions.class"; import {Subscription} from "rxjs"; import {EnvProperties} from "../../utils/properties/env-properties"; import {properties} from "../../../../environments/environment"; +import {ClickEvent} from "../../utils/click/click-outside-or-esc.directive"; export type InputType = 'text' | 'URL' | 'logoURL' | 'autocomplete' | 'autocomplete_soft' | 'textarea' | 'select' | 'chips'; @@ -49,8 +50,8 @@ declare var UIkit; [class.focused]="focused" [ngClass]="inputClass" [class.hint]="hint" [class.active]="(formAsControl?.value || formAsArray?.length > 0 || getLabel(formAsControl?.value)) && !focused" [class.danger]="(formControl.invalid && (formControl.touched || searchControl?.touched)) || (searchControl?.invalid && searchControl?.touched)"> -
+
@@ -267,11 +268,8 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang } } - @HostListener('document:click', ['$event']) - click(event) { - if(event.isTrusted) { - this.focus(this.inputBox && this.inputBox.nativeElement.contains(event.target), event); - } + click(event: ClickEvent) { + this.focus(!event.clicked, event); } ngOnInit() { @@ -401,11 +399,7 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang } }); } - - stopPropagation() { - event.stopPropagation(); - } - + remove(index: number, event) { this.formAsArray.removeAt(index); this.formAsArray.markAsDirty(); @@ -439,7 +433,6 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang } this.formAsArray.push(new FormControl(this.searchControl.value, this.validators)); this.formAsArray.markAsDirty(); - this.focus(true); } this.searchControl.setValue(''); } @@ -470,6 +463,13 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang } } else { this.open(false); + if (this.input) { + this.input.nativeElement.blur(); + } else if (this.textArea) { + this.textArea.nativeElement.blur(); + } else if (this.searchInput) { + this.searchInput.nativeElement.blur(); + } if (this.searchControl) { this.add(event); } diff --git a/sharedComponents/input/input.module.ts b/sharedComponents/input/input.module.ts index de3d38da..9ab02dd3 100644 --- a/sharedComponents/input/input.module.ts +++ b/sharedComponents/input/input.module.ts @@ -3,12 +3,14 @@ import {InputComponent} from "./input.component"; import {SharedModule} from "../../shared/shared.module"; import {IconsModule} from "../../utils/icons/icons.module"; import {SafeHtmlPipeModule} from "../../utils/pipes/safeHTMLPipe.module"; +import {ClickModule} from "../../utils/click/click.module"; @NgModule({ imports: [ SharedModule, IconsModule, - SafeHtmlPipeModule + SafeHtmlPipeModule, + ClickModule ], exports: [ InputComponent diff --git a/sharedComponents/search-input/search-input.component.ts b/sharedComponents/search-input/search-input.component.ts index 1baa238c..28fe3d6d 100644 --- a/sharedComponents/search-input/search-input.component.ts +++ b/sharedComponents/search-input/search-input.component.ts @@ -12,16 +12,17 @@ import { import {AbstractControl} from '@angular/forms'; import {MatAutocompleteTrigger} from '@angular/material/autocomplete'; import {InputComponent} from "../input/input.component"; +import {ClickEvent} from "../../utils/click/click-outside-or-esc.directive"; @Component({ selector: '[search-input]', template: `
-
+
@@ -66,10 +67,9 @@ export class SearchInputComponent implements OnInit { } } - @HostListener('document:click', ['$event']) - click(event) { - if(event.isTrusted && this.expandable && !this.disabled) { - this.expand(this.searchInput && this.searchInput.nativeElement.contains(event.target)); + click(event: ClickEvent) { + if(this.expandable && !this.disabled) { + this.expand(!event.clicked); } } diff --git a/sharedComponents/search-input/search-input.module.ts b/sharedComponents/search-input/search-input.module.ts index 845a0f77..4097c05d 100644 --- a/sharedComponents/search-input/search-input.module.ts +++ b/sharedComponents/search-input/search-input.module.ts @@ -4,9 +4,10 @@ import {SearchInputComponent} from './search-input.component'; import {MatAutocompleteModule} from '@angular/material/autocomplete'; import {IconsModule} from '../../utils/icons/icons.module'; import {InputModule} from "../input/input.module"; +import {ClickModule} from "../../utils/click/click.module"; @NgModule({ - imports: [SharedModule, MatAutocompleteModule, IconsModule, InputModule], + imports: [SharedModule, MatAutocompleteModule, IconsModule, InputModule, ClickModule], declarations: [SearchInputComponent], exports: [SearchInputComponent] }) diff --git a/utils/click/click-outside-or-esc.directive.ts b/utils/click/click-outside-or-esc.directive.ts index 420d48fa..48b906d1 100644 --- a/utils/click/click-outside-or-esc.directive.ts +++ b/utils/click/click-outside-or-esc.directive.ts @@ -1,79 +1,35 @@ -import {Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core'; -import {fromEvent, Subscriber} from 'rxjs'; -import {delay, tap} from 'rxjs/operators'; +import {Directive, ElementRef, EventEmitter, HostListener, Output} from '@angular/core'; + +export interface ClickEvent { + event: any, + clicked: boolean; +} @Directive({ selector: '[click-outside-or-esc]' }) +export class ClickOutsideOrEsc { + @Output('clickOutside') clickOutside: EventEmitter = new EventEmitter(); -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; - - constructor(private _elRef: ElementRef) { - this.listening = false; - this.clickOutside = new EventEmitter(); - } - - ngOnInit() { - if(typeof document !== 'undefined') { - this.subscriptions.push(fromEvent(document, 'click').pipe( - delay(1), - tap(() => { - this.listening = true; - })).subscribe((event: MouseEvent) => { - this.onGlobalClick(event); - })); - this.subscriptions.push(fromEvent(document, 'click').pipe( - delay(1), - tap(() => { - 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) => { - subscription.unsubscribe(); + constructor(private elementRef: ElementRef) {} + + @HostListener('document:click', ['$event']) + click(event) { + if(event.isTrusted) { + this.clickOutside.emit({ + event: event, + clicked: !(this.elementRef && this.elementRef.nativeElement.contains(event.target)) }); } - this.subscriptions = []; } - - onGlobalClick(event: MouseEvent) { - if (event instanceof MouseEvent && this.listening === true) { - let element: 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 - }); - } + + @HostListener('window:keydown', ['$event']) + keyEvent(event: KeyboardEvent) { + if(event.code === 'Escape') { + this.clickOutside.emit({ + event: event, + clicked: true + }); } } }