[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:
parent
10c40abc05
commit
6b90c17e62
|
@ -15,7 +15,8 @@ import {Observable, of, Subscription} from "rxjs";
|
||||||
import {MatSelect} from "@angular/material/select";
|
import {MatSelect} from "@angular/material/select";
|
||||||
import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
|
import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
|
||||||
import {map, startWith} from "rxjs/operators";
|
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 {
|
export interface Option {
|
||||||
|
@ -52,21 +53,6 @@ export interface Option {
|
||||||
<input class="uk-input" [placeholder]="placeholder" [formControl]="formControl">
|
<input class="uk-input" [placeholder]="placeholder" [formControl]="formControl">
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</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'">
|
<ng-template [ngIf]="type === 'textarea'">
|
||||||
<div [ngClass]="inputClass" class="uk-padding-remove-right"
|
<div [ngClass]="inputClass" class="uk-padding-remove-right"
|
||||||
[class.uk-form-danger]="formControl.invalid && formControl.touched"
|
[class.uk-form-danger]="formControl.invalid && formControl.touched"
|
||||||
|
@ -97,6 +83,37 @@ export interface Option {
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</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'">
|
<ng-template [ngIf]="type === 'chips'">
|
||||||
<div [ngClass]="inputClass"
|
<div [ngClass]="inputClass"
|
||||||
[attr.uk-tooltip]="formControl.disabled?'title: This field is not editable; pos: bottom-left':null"
|
[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 */
|
/** Internal basic information */
|
||||||
public required: boolean = false;
|
public required: boolean = false;
|
||||||
private initValue: any;
|
private initValue: any;
|
||||||
/** Chips */
|
/** Chips && Autocomplete*/
|
||||||
public filteredOptions: Observable<Option[]>;
|
public filteredOptions: Observable<Option[]>;
|
||||||
public searchControl: FormControl;
|
public searchControl: FormControl;
|
||||||
private subscriptions: any[] = [];
|
private subscriptions: any[] = [];
|
||||||
/** Autocomplete */
|
|
||||||
@Input()
|
|
||||||
public autocompleteList: string[] = [];
|
|
||||||
public autocompleteFilteredList: Observable<string[]>;
|
|
||||||
@ViewChild('select') select: MatSelect;
|
@ViewChild('select') select: MatSelect;
|
||||||
@ViewChild('searchInput') searchInput: ElementRef;
|
@ViewChild('searchInput') searchInput: ElementRef;
|
||||||
focused: boolean = false;
|
focused: boolean = false;
|
||||||
|
@ -231,17 +244,18 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges {
|
||||||
if(this.type === 'logoURL') {
|
if(this.type === 'logoURL') {
|
||||||
this.secure = (!this.initValue || this.initValue.includes('https://'));
|
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.filteredOptions = of(this.options);
|
||||||
this.searchControl = new FormControl('');
|
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(''),
|
this.filteredOptions = this.searchControl.valueChanges.pipe(startWith(''),
|
||||||
map(option => this.filter(option)));
|
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) {
|
if (this.formControl && this.formControl.validator) {
|
||||||
let validator = this.formControl.validator({} as AbstractControl);
|
let validator = this.formControl.validator({} as AbstractControl);
|
||||||
this.required = (validator && validator.required);
|
this.required = (validator && validator.required);
|
||||||
|
@ -286,8 +300,6 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges {
|
||||||
this.formAsArray.removeAt(index);
|
this.formAsArray.removeAt(index);
|
||||||
this.formAsArray.markAsDirty();
|
this.formAsArray.markAsDirty();
|
||||||
this.searchControl.setValue('');
|
this.searchControl.setValue('');
|
||||||
this.searchInput.nativeElement.focus();
|
|
||||||
this.searchInput.nativeElement.value = '';
|
|
||||||
this.stopPropagation();
|
this.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,25 +307,21 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges {
|
||||||
this.formAsArray.push(new FormControl(event.option.value));
|
this.formAsArray.push(new FormControl(event.option.value));
|
||||||
this.formAsArray.markAsDirty();
|
this.formAsArray.markAsDirty();
|
||||||
this.searchControl.setValue('');
|
this.searchControl.setValue('');
|
||||||
this.searchInput.nativeElement.focus();
|
|
||||||
this.searchInput.nativeElement.value = '';
|
|
||||||
this.stopPropagation();
|
this.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
private filter(value: string): Option[] {
|
private filter(value: string): Option[] {
|
||||||
let options = this.options.filter(option => !this.formAsArray.value.find(value => option.value === value));
|
let options = this.options;
|
||||||
if ((!value || value.length == 0) && !this.showOptionsOnEmpty) {
|
if(this.type === "chips") {
|
||||||
return [];
|
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();
|
const filterValue = value.toString().toLowerCase();
|
||||||
return options.filter(option => option.label.toLowerCase().indexOf(filterValue) != -1);
|
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) {
|
add(event: MatChipInputEvent) {
|
||||||
if (this.addExtraChips && event.value) {
|
if (this.addExtraChips && event.value) {
|
||||||
this.stopPropagation();
|
this.stopPropagation();
|
||||||
|
@ -328,4 +336,10 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges {
|
||||||
let option = this.options.find(option => option.value === value);
|
let option = this.options.find(option => option.value === value);
|
||||||
return (option) ? option.label : value;
|
return (option) ? option.label : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetSearch(event: any, value: string = null) {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.formControl.setValue(null);
|
||||||
|
this.searchControl.setValue(this.getLabel(value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue