[Library | Trunk]: Fix autocomplete input

git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-services-library/trunk/ng-openaire-library/src/app@60674 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
k.triantafyllou 2021-03-19 14:23:47 +00:00
parent 10c40abc05
commit 6b90c17e62
1 changed files with 53 additions and 39 deletions

View File

@ -15,7 +15,8 @@ import {Observable, of, Subscription} from "rxjs";
import {MatSelect} from "@angular/material/select";
import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
import {map, startWith} from "rxjs/operators";
import {MatChipInputEvent} from "@angular/material/chips";
import {MatChipInputEvent, MatChipSelectionChange} from "@angular/material/chips";
import {THIS_EXPR} from "@angular/compiler/src/output/output_ast";
export interface Option {
@ -52,21 +53,6 @@ export interface Option {
<input class="uk-input" [placeholder]="placeholder" [formControl]="formControl">
</div>
</ng-template>
<ng-template [ngIf]="type === 'autocomplete'">
<div [ngClass]="inputClass"
[class.uk-form-danger]="formControl.invalid && formControl.touched"
[attr.uk-tooltip]="formControl.disabled?'title: This field is not editable; pos: bottom-left':''">
<input class="uk-input"
[placeholder]="placeholder"
[formControl]="formControl"
[matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of autocompleteFilteredList | async" [value]="option">
{{option}}
</mat-option>
</mat-autocomplete>
</div>
</ng-template>
<ng-template [ngIf]="type === 'textarea'">
<div [ngClass]="inputClass" class="uk-padding-remove-right"
[class.uk-form-danger]="formControl.invalid && formControl.touched"
@ -97,6 +83,37 @@ export interface Option {
</mat-form-field>
</div>
</ng-template>
<ng-template [ngIf]="type === 'autocomplete'">
<div [ngClass]="inputClass"
[attr.uk-tooltip]="formControl.disabled?'title: This field is not editable; pos: bottom-left':null"
[class.clickable]="formControl.enabled"
[class.uk-form-danger]="formControl.invalid && formControl.touched" (click)="openSelect()">
<mat-form-field class="uk-width-1-1">
<mat-chip-list #chipList>
<mat-chip *ngIf="formControl.value" (click)="resetSearch($event, formControl.value)" [selectable]="false" [removable]="removable"
[attr.uk-tooltip]="getLabel(formControl.value)">
<span class="uk-flex uk-flex-middle">
<span class="uk-width-expand uk-text-truncate" [class.uk-text-small]="smallChip">{{getLabel(formControl.value)}}</span>
<icon name="remove_circle" class="mat-chip-remove" [flex]="true" [ratio]="smallChip?0.8:1"
(click)="resetSearch($event)"></icon>
</span>
</mat-chip>
<div [class.uk-hidden]="formControl.value" class="uk-width-expand uk-position-relative chip-input">
<input #searchInput class="uk-width-1-1" [formControl]="searchControl" [matAutocomplete]="auto"
[matChipInputFor]="chipList" [matAutocompleteConnectedTo]="origin">
<div *ngIf="placeholder && !searchControl.value" class="placeholder uk-width-1-1"
(click)="searchInput.focus()">{{placeholder}}</div>
</div>
<div class="uk-width-1-1 uk-invisible" matAutocompleteOrigin #origin="matAutocompleteOrigin"></div>
</mat-chip-list>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="formControl.setValue($event.option.value)" [class]="panelClass" [panelWidth]="panelWidth">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option.value">
{{option.label}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
</ng-template>
<ng-template [ngIf]="type === 'chips'">
<div [ngClass]="inputClass"
[attr.uk-tooltip]="formControl.disabled?'title: This field is not editable; pos: bottom-left':null"
@ -189,14 +206,10 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges {
/** Internal basic information */
public required: boolean = false;
private initValue: any;
/** Chips */
/** Chips && Autocomplete*/
public filteredOptions: Observable<Option[]>;
public searchControl: FormControl;
private subscriptions: any[] = [];
/** Autocomplete */
@Input()
public autocompleteList: string[] = [];
public autocompleteFilteredList: Observable<string[]>;
@ViewChild('select') select: MatSelect;
@ViewChild('searchInput') searchInput: ElementRef;
focused: boolean = false;
@ -231,17 +244,18 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges {
if(this.type === 'logoURL') {
this.secure = (!this.initValue || this.initValue.includes('https://'));
}
if (this.options && this.type === 'chips') {
if (this.options && (this.type === 'chips' || this.type === 'autocomplete')) {
this.filteredOptions = of(this.options);
this.searchControl = new FormControl('');
this.subscriptions.push(this.searchControl.valueChanges.subscribe(value => {
setTimeout(() => {
this.searchInput.nativeElement.focus();
this.searchInput.nativeElement.value = value;
},0);
}));
this.filteredOptions = this.searchControl.valueChanges.pipe(startWith(''),
map(option => this.filter(option)));
}
if(this.autocompleteList && this.type === 'autocomplete') {
this.autocompleteFilteredList = of(this.autocompleteList);
this.autocompleteFilteredList = this.formControl.valueChanges.pipe(startWith(''),
map(value => this.simpleFilter(value)));
}
if (this.formControl && this.formControl.validator) {
let validator = this.formControl.validator({} as AbstractControl);
this.required = (validator && validator.required);
@ -286,8 +300,6 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges {
this.formAsArray.removeAt(index);
this.formAsArray.markAsDirty();
this.searchControl.setValue('');
this.searchInput.nativeElement.focus();
this.searchInput.nativeElement.value = '';
this.stopPropagation();
}
@ -295,25 +307,21 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges {
this.formAsArray.push(new FormControl(event.option.value));
this.formAsArray.markAsDirty();
this.searchControl.setValue('');
this.searchInput.nativeElement.focus();
this.searchInput.nativeElement.value = '';
this.stopPropagation();
}
private filter(value: string): Option[] {
let options = this.options.filter(option => !this.formAsArray.value.find(value => option.value === value));
if ((!value || value.length == 0) && !this.showOptionsOnEmpty) {
return [];
let options = this.options;
if(this.type === "chips") {
options = options.filter(option => !this.formAsArray.value.find(value => option.value === value));
}
if ((!value || value.length == 0)) {
return (this.showOptionsOnEmpty)?options:[];
}
const filterValue = value.toString().toLowerCase();
return options.filter(option => option.label.toLowerCase().indexOf(filterValue) != -1);
}
private simpleFilter(value: string): string[] {
const filterValue = value.toLowerCase();
return this.autocompleteList.filter(option => option.toLowerCase().includes(filterValue));
}
add(event: MatChipInputEvent) {
if (this.addExtraChips && event.value) {
this.stopPropagation();
@ -328,4 +336,10 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges {
let option = this.options.find(option => option.value === value);
return (option) ? option.label : value;
}
resetSearch(event: any, value: string = null) {
event.stopPropagation();
this.formControl.setValue(null);
this.searchControl.setValue(this.getLabel(value));
}
}