Add key bind for option selection and make options more flexible

This commit is contained in:
Konstantinos Triantafyllou 2022-04-04 16:44:00 +03:00
parent 70ea6ec60c
commit bd0b7a9e9a
1 changed files with 56 additions and 6 deletions

View File

@ -107,7 +107,7 @@ declare var UIkit;
<div class="options uk-dropdown" *ngIf="filteredOptions && filteredOptions.length > 0 && opened" #optionBox
uk-dropdown="pos: bottom-justify; mode: click; offset: 15; boundary-align: true;" [attr.boundary]="'#' + id">
<ul class="uk-nav uk-dropdown-nav">
<li *ngFor="let option of filteredOptions" [class.uk-active]="formControl.value === option.value"
<li *ngFor="let option of filteredOptions; let i=index" [class.uk-active]="(formControl.value === option.value) || selectedIndex === i"
[attr.uk-tooltip]="(tooltip)?('title: ' + option.label + ';'):null">
<a (click)="selectOption(option, $event)">{{option.label}}</a>
</li>
@ -171,9 +171,9 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
@ViewChild('textArea') textArea: ElementRef;
@Input('rows') rows: number = 3;
/** Select | Autocomplete | chips available options */
@Input('options') options: Option[] = [];
@Input() tooltip: boolean = false;
@Input() selectArrow: string = 'arrow_drop_down';
@Input() selectedIndex: number = 0;
/** Chips && Autocomplete*/
public filteredOptions: Option[] = [];
public searchControl: FormControl;
@ -195,6 +195,7 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
public opened: boolean = false;
public properties: EnvProperties = properties;
private initValue: any;
private optionsArray: Option[] = [];
private subscriptions: any[] = [];
@ViewChild('inputBox') inputBox: ElementRef;
@ViewChild('optionBox') optionBox: ElementRef;
@ -213,12 +214,51 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
}
}
@Input()
set options(options: (Option | string) []) {
this.optionsArray = options.map(option => {
if(typeof option === 'string') {
return {
label: option,
value: option
}
} else {
return option
}
});
}
constructor(private elementRef: ElementRef, private cdr: ChangeDetectorRef) {
if (elementRef.nativeElement.hasAttribute('dashboard-input') && this.properties.environment === "development") {
console.warn("'dashboard-input' selector is deprecated; use 'input' instead.");
}
}
@HostListener('window:keydown', ['$event'])
keyEvent(event: KeyboardEvent) {
if(this.opened) {
if(event.key === 'ArrowUp') {
event.preventDefault();
if(this.selectedIndex > 0) {
this.selectedIndex--;
this.optionBox.nativeElement.scrollBy(0, -34);
}
} else if(event.key === 'ArrowDown') {
event.preventDefault();
if(this.selectedIndex < (this.filteredOptions.length - 1)) {
this.selectedIndex++;
this.optionBox.nativeElement.scrollBy(0, 34);
}
} else if(event.key === 'Enter') {
event.preventDefault();
if(this.filteredOptions[this.selectedIndex]) {
this.selectOption(this.filteredOptions[this.selectedIndex], event);
this.open(false);
}
}
}
}
@HostListener('document:click', ['$event'])
click(event) {
this.focus(this.inputBox && this.inputBox.nativeElement.contains(event.target), event);
@ -283,7 +323,7 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
if (this.type === 'logoURL') {
this.secure = (!this.initValue || this.initValue.includes('https://'));
}
if (this.options) {
if (this.optionsArray) {
this.filteredOptions = this.filter('');
}
if (this.type === 'chips' || this.type === 'autocomplete') {
@ -348,15 +388,21 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
}
private filter(value: string): Option[] {
let options = this.options;
let options = this.optionsArray;
if (this.type === "chips") {
options = options.filter(option => !this.formAsArray.value.find(value => HelperFunctions.equals(option.value, value)));
}
if ((!value || value.length == 0)) {
this.selectedIndex = 0;
return (this.showOptionsOnEmpty) ? options : [];
}
const filterValue = value.toString().toLowerCase();
return options.filter(option => option.label.toLowerCase().indexOf(filterValue) != -1);
options = options.filter(option => option.label.toLowerCase().indexOf(filterValue) != -1);
this.selectedIndex = options.findIndex(option => option.value === this.formControl.value);
if(this.selectedIndex === -1) {
this.selectedIndex = 0;
}
return options;
}
add(event) {
@ -372,7 +418,7 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
}
getLabel(value: any) {
let option = this.options.find(option => HelperFunctions.equals(option.value, value));
let option = this.filteredOptions.find(option => HelperFunctions.equals(option.value, value));
return (option) ? option.label : (value);
}
@ -409,6 +455,10 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
this.cdr.detectChanges();
if (this.optionBox) {
if (this.opened) {
this.selectedIndex = this.filteredOptions.findIndex(option => option.value === this.formControl.value);
if(this.selectedIndex === -1) {
this.selectedIndex = 0;
}
UIkit.dropdown(this.optionBox.nativeElement).show();
} else {
UIkit.dropdown(this.optionBox.nativeElement).hide();