openaire-library/sharedComponents/search-input/search-input.component.ts

106 lines
3.9 KiB
TypeScript

import {Component, ElementRef, EventEmitter, Input, Output, ViewChild} from '@angular/core';
import {AbstractControl} from '@angular/forms';
import {MatAutocompleteTrigger} from '@angular/material/autocomplete';
@Component({
selector: '[search-input]',
styleUrls: ['search-input.component.css'],
template: `
<div class="uk-flex uk-flex-middle uk-flex-center search-input" [ngClass]="colorClass">
<div *ngIf="control" class="uk-width-expand" [class.bordered]="bordered && (showSearch || selected)" [class.focused]="showSearch">
<form (ngSubmit)="search()">
<input #input type="text" class="uk-width-1-1"
[class.uk-animation-slide-right-medium]="showSearch"
[class.uk-hidden@m]="!showSearch"
[placeholder]="placeholder"
(blur)="closeSearch()"
[formControl]="control"
[matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="search()">
<mat-option *ngFor="let option of list | async" [value]="option">
{{option}}
</mat-option>
</mat-autocomplete>
</form>
<div *ngIf="selected && !showSearch" class="uk-flex selected uk-padding-small uk-visible@m">
<span class="uk-flex uk-flex-middle clickable" style="max-width: 100%" [class.uk-width-1-1]="bordered">
<span class="uk-width-expand uk-text-truncate" (click)="toggle()">{{selected}}</span>
<icon name="close" class="space" [ratio]="0.8" (click)="resetEmitter.emit()"></icon>
</span>
</div>
</div>
<button [disabled]="loading" class="search uk-flex uk-flex-middle uk-margin-medium-left uk-visible@m"
(mousedown)="$event.preventDefault()" (click)="toggle()"
[attr.uk-tooltip]="'title: '+placeholder+'; cls: uk-padding-small uk-active'">
<span [ngClass]="colorClass" class="icon-bg">
<icon class="uk-position-center" name="search"></icon>
</span>
<span class="uk-text-uppercase overlay">{{toggleTitle}}</span>
</button>
<button [disabled]="loading" class="search uk-flex uk-flex-middle uk-hidden@m"
(mousedown)="$event.preventDefault()" (click)="search()"
[attr.uk-tooltip]="'title: '+placeholder+'; cls: uk-padding-small uk-active'">
<span [ngClass]="colorClass" class="icon-bg">
<icon class="uk-position-center" name="search"></icon>
</span>
<span class="uk-text-uppercase overlay">{{toggleTitle}}</span>
</button>
</div>`
})
export class SearchInputComponent {
@Input()
showSearch: boolean = true;
@Input()
control: AbstractControl;
@Input()
placeholder: string;
@Input()
loading: boolean = false;
@Input()
selected: any;
@Input()
list: any = null;
@Input()
colorClass: string = 'portal-color';
@Input()
bordered: boolean = false;
@Input()
toggleTitle: string = 'search';
@ViewChild('input') input: ElementRef;
@ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger;
@Output()
searchEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
@Output()
resetEmitter: EventEmitter<any> = new EventEmitter<any>();
@Output()
closeEmitter: EventEmitter<any> = new EventEmitter<any>();
toggle() {
this.showSearch = !this.showSearch;
if (this.showSearch) {
setTimeout(() => { // this will make the execution after the above boolean has changed
this.input.nativeElement.focus();
}, 0);
}
}
closeSearch() {
this.showSearch = false;
this.closeEmitter.emit();
}
public search(emit = true) {
this.trigger.closePanel();
this.searchEmitter.emit(emit);
}
public reset() {
this.control.setValue('');
this.input.nativeElement.value = '';
this.showSearch = true;
setTimeout(() => {
this.input.nativeElement.focus();
}, 0);
}
}