-
-
-
-
+
+
+
+
-
+
diff --git a/ui/src/app/shared/autocomplete/autocomplete.component.scss b/ui/src/app/shared/autocomplete/autocomplete.component.scss
index f794dce0c..262779eab 100644
--- a/ui/src/app/shared/autocomplete/autocomplete.component.scss
+++ b/ui/src/app/shared/autocomplete/autocomplete.component.scss
@@ -12,6 +12,8 @@
}
:host {
+ position: relative;
+
.btn-outline-secondary {
border-color: $input-border-color;
}
diff --git a/ui/src/app/shared/autocomplete/autocomplete.component.ts b/ui/src/app/shared/autocomplete/autocomplete.component.ts
index bc9994b1a..28a4c0365 100644
--- a/ui/src/app/shared/autocomplete/autocomplete.component.ts
+++ b/ui/src/app/shared/autocomplete/autocomplete.component.ts
@@ -5,21 +5,22 @@ import {
EventEmitter,
OnInit,
OnDestroy,
+ OnChanges,
AfterViewInit,
ViewChild,
ViewChildren,
QueryList,
ElementRef,
- SimpleChanges,
forwardRef,
- ChangeDetectionStrategy,
- OnChanges,
- HostListener
+ HostListener,
+ SimpleChanges
} from '@angular/core';
-import { FormControl, ControlValueAccessor, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
+import { FormControl, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Observable, Subject, Subscription, interval } from 'rxjs';
import { takeUntil, combineLatest, map } from 'rxjs/operators';
+import { LiveAnnouncer } from '@angular/cdk/a11y';
+
import { keyCodes } from '../../shared/keycodes';
import { AutoCompleteStateEmitter } from './autocomplete.model';
import { NavigatorService } from '../../core/service/navigator.service';
@@ -28,7 +29,6 @@ const POLL_TIMEOUT = 1000;
const INPUT_FIELD_INDEX = -1;
@Component({
- changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'auto-complete',
templateUrl: './autocomplete.component.html',
styleUrls: ['./autocomplete.component.scss'],
@@ -40,7 +40,7 @@ const INPUT_FIELD_INDEX = -1;
}
]
})
-export class AutoCompleteComponent implements OnInit, OnDestroy, AfterViewInit, ControlValueAccessor {
+export class AutoCompleteComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit, ControlValueAccessor {
@Input() defaultValue = '';
@Input() matches: string[] = [];
@Input() id: string;
@@ -69,8 +69,6 @@ export class AutoCompleteComponent implements OnInit, OnDestroy, AfterViewInit,
$pollSubscription: Subscription;
showMoreAvailable: boolean;
-
- matches$: Observable
;
numMatches: number;
input: FormControl = new FormControl();
@@ -84,7 +82,7 @@ export class AutoCompleteComponent implements OnInit, OnDestroy, AfterViewInit,
propagateChange = (_: any | null) => { };
propagateTouched = (_: any | null) => { };
- constructor(private navigator: NavigatorService) {}
+ constructor(private navigator: NavigatorService, private live: LiveAnnouncer) {}
ngOnInit(): void {
this.$pollInput = interval(POLL_TIMEOUT);
@@ -116,7 +114,14 @@ export class AutoCompleteComponent implements OnInit, OnDestroy, AfterViewInit,
}
ngAfterViewInit(): void {
- this.listItems.changes.subscribe((changes) => this.setElementReferences(changes));
+ this.listItems.changes.subscribe((changes) => this.setElementReferences(changes) );
+ }
+
+ ngOnChanges(changes: SimpleChanges): void {
+ if (changes.matches && this.matches) {
+ const count = this.matches.length;
+ this.live.announce(count === 0 ? 'No results available' : `${count} result${count === 1 ? '' : 's'} available`);
+ }
}
writeValue(value: any): void {
@@ -242,6 +247,7 @@ export class AutoCompleteComponent implements OnInit, OnDestroy, AfterViewInit,
});
}
+ @HostListener('keydown', ['$event'])
handleKeyDown(event: KeyboardEvent): void {
switch (keyCodes[event.keyCode]) {
case 'up':
@@ -338,7 +344,7 @@ export class AutoCompleteComponent implements OnInit, OnDestroy, AfterViewInit,
}
getOptionId(index): string {
- return `${this.id}__option--${index}`;
+ return `${this.fieldId}__option--${index}`;
}
get hasAutoselect(): boolean {