1- import { ChangeDetectorRef , Component , EventEmitter , Input , OnInit , Output } from '@angular/core' ;
1+ import {
2+ ChangeDetectorRef ,
3+ Component ,
4+ EventEmitter ,
5+ Input ,
6+ OnInit ,
7+ Output ,
8+ ViewChild ,
9+ ElementRef
10+ } from '@angular/core' ;
211import { UntypedFormGroup } from '@angular/forms' ;
312
413import { Observable , of as observableOf } from 'rxjs' ;
@@ -28,6 +37,8 @@ import { FormFieldMetadataValueObject } from '../../../models/form-field-metadat
2837 templateUrl : './dynamic-scrollable-dropdown.component.html'
2938} )
3039export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyComponent implements OnInit {
40+ @ViewChild ( 'dropdownMenu' , { read : ElementRef } ) dropdownMenu : ElementRef ;
41+
3142 @Input ( ) bindId = true ;
3243 @Input ( ) group : UntypedFormGroup ;
3344 @Input ( ) model : DynamicScrollableDropdownModel ;
@@ -41,6 +52,7 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
4152 public pageInfo : PageInfo ;
4253 public optionsList : any ;
4354 public inputText : string = null ;
55+ public selectedIndex = 0 ;
4456 public acceptableKeys = [ 'Space' , 'NumpadMultiply' , 'NumpadAdd' , 'NumpadSubtract' , 'NumpadDecimal' , 'Semicolon' , 'Equal' , 'Comma' , 'Minus' , 'Period' , 'Quote' , 'Backquote' ] ;
4557
4658 constructor ( protected vocabularyService : VocabularyService ,
@@ -73,6 +85,7 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
7385 list . pageInfo . totalElements ,
7486 list . pageInfo . totalPages
7587 ) ;
88+ this . selectedIndex = 0 ;
7689 this . cdr . detectChanges ( ) ;
7790 } ) ;
7891 }
@@ -96,6 +109,23 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
96109 }
97110 }
98111
112+ navigateDropdown ( event : KeyboardEvent ) {
113+ if ( event . key === 'ArrowDown' ) {
114+ this . selectedIndex = Math . min ( this . selectedIndex + 1 , this . optionsList . length - 1 ) ;
115+ } else if ( event . key === 'ArrowUp' ) {
116+ this . selectedIndex = Math . max ( this . selectedIndex - 1 , 0 ) ;
117+ }
118+ this . scrollToSelected ( ) ;
119+ }
120+
121+ scrollToSelected ( ) {
122+ const dropdownItems = this . dropdownMenu . nativeElement . querySelectorAll ( '.dropdown-item' ) ;
123+ const selectedItem = dropdownItems [ this . selectedIndex ] ;
124+ if ( selectedItem ) {
125+ selectedItem . scrollIntoView ( { block : 'nearest' } ) ;
126+ }
127+ }
128+
99129 /**
100130 * KeyDown handler to allow toggling the dropdown via keyboard
101131 * @param event KeyboardEvent
@@ -104,12 +134,19 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
104134 selectOnKeyDown ( event : KeyboardEvent , sdRef : NgbDropdown ) {
105135 const keyName = event . key ;
106136
107- if ( keyName === ' ' || keyName === ' Enter') {
137+ if ( keyName === 'Enter' ) {
108138 event . preventDefault ( ) ;
109139 event . stopPropagation ( ) ;
110- sdRef . toggle ( ) ;
140+ if ( sdRef . isOpen ( ) ) {
141+ this . onSelect ( this . optionsList [ this . selectedIndex ] ) ;
142+ sdRef . close ( ) ;
143+ } else {
144+ sdRef . open ( ) ;
145+ }
111146 } else if ( keyName === 'ArrowDown' || keyName === 'ArrowUp' ) {
112- this . openDropdown ( sdRef ) ;
147+ event . preventDefault ( ) ;
148+ event . stopPropagation ( ) ;
149+ this . navigateDropdown ( event ) ;
113150 } else if ( keyName === 'Backspace' ) {
114151 this . removeKeyFromInput ( ) ;
115152 } else if ( this . isAcceptableKey ( keyName ) ) {
0 commit comments