@@ -121,7 +121,7 @@ export class DropdownList implements AbstractDropdownView, AfterViewInit, OnDest
121121 /**
122122 * The list items belonging to the `DropdownList`.
123123 */
124- @Input ( ) set items ( value : Array < ListItem > | Observable < Array < ListItem > > ) {
124+ @Input ( ) set items ( value : Array < ListItem > | Observable < Array < ListItem > > ) {
125125 if ( isObservable ( value ) ) {
126126 if ( this . _itemsSubscription ) {
127127 this . _itemsSubscription . unsubscribe ( ) ;
@@ -283,6 +283,11 @@ export class DropdownList implements AbstractDropdownView, AfterViewInit, OnDest
283283 filterBy ( query = "" ) {
284284 if ( query ) {
285285 this . displayItems = this . getListItems ( ) . filter ( item => item . content . toLowerCase ( ) . includes ( query . toLowerCase ( ) ) ) ;
286+ // Reset index if items were found
287+ // Prevent selecting index in list that are undefined.
288+ if ( this . displayItems ) {
289+ this . index = 0 ;
290+ }
286291 } else {
287292 this . displayItems = this . getListItems ( ) ;
288293 }
@@ -328,23 +333,26 @@ export class DropdownList implements AbstractDropdownView, AfterViewInit, OnDest
328333 * Returns the `HTMLElement` for the item that is subsequent to the selected item.
329334 */
330335 getNextElement ( ) : HTMLElement {
331- if ( this . index < this . displayItems . length - 1 ) {
332- this . index ++ ;
333- }
334- let item = this . displayItems [ this . index ] ;
335- if ( item . disabled ) {
336- return this . getNextElement ( ) ;
336+ // Only return native elements if they are rendered
337+ const elemList = this . listElementList ? this . listElementList . toArray ( ) : [ ] ;
338+ if ( ! elemList . length ) {
339+ return null ;
337340 }
338341
339- let elemList = this . listElementList ? this . listElementList . toArray ( ) : [ ] ;
340-
341- // TODO: update to optional chaining after upgrading typescript
342- // to v3.7+
343- if ( elemList [ this . index ] && elemList [ this . index ] . nativeElement ) {
344- return elemList [ this . index ] . nativeElement ;
345- } else {
346- return null ;
342+ /**
343+ * Start checking from next index
344+ * Continue looping through the list until a non disabeled element is found or
345+ * end of list is reached
346+ */
347+ for ( let i = this . index + 1 ; i < elemList . length ; i ++ ) {
348+ // If the values in the list are not disabled
349+ if ( ! this . displayItems [ i ] . disabled ) {
350+ this . index = i ;
351+ return elemList [ i ] . nativeElement ;
352+ }
347353 }
354+
355+ return elemList [ this . index ] . nativeElement ;
348356 }
349357
350358 /**
@@ -368,23 +376,26 @@ export class DropdownList implements AbstractDropdownView, AfterViewInit, OnDest
368376 * Returns the `HTMLElement` for the item that precedes the selected item.
369377 */
370378 getPrevElement ( ) : HTMLElement {
371- if ( this . index > 0 ) {
372- this . index -- ;
373- }
374- let item = this . displayItems [ this . index ] ;
375- if ( item . disabled ) {
376- return this . getPrevElement ( ) ;
379+ // Only return native elements if they are rendered
380+ const elemList = this . listElementList ? this . listElementList . toArray ( ) : [ ] ;
381+ if ( ! elemList . length ) {
382+ return null ;
377383 }
378384
379- let elemList = this . listElementList ? this . listElementList . toArray ( ) : [ ] ;
380-
381- // TODO: update to optional chaining after upgrading typescript
382- // to v3.7+
383- if ( elemList [ this . index ] && elemList [ this . index ] . nativeElement ) {
384- return elemList [ this . index ] . nativeElement ;
385- } else {
386- return null ;
385+ /**
386+ * Start checking from next index
387+ * Continue looping through the list until a non disabeled element is found or
388+ * end of list is reached
389+ */
390+ for ( let i = this . index - 1 ; i < this . index && i >= 0 ; i -- ) {
391+ // If the values in the list are not disabled
392+ if ( ! this . displayItems [ i ] . disabled ) {
393+ this . index = i ;
394+ return elemList [ i ] . nativeElement ;
395+ }
387396 }
397+
398+ return elemList [ this . index ] . nativeElement ;
388399 }
389400
390401 /**
@@ -502,7 +513,7 @@ export class DropdownList implements AbstractDropdownView, AfterViewInit, OnDest
502513 event . preventDefault ( ) ;
503514 if ( event . key === "ArrowDown" ) {
504515 if ( this . hasNextElement ( ) ) {
505- this . getNextElement ( ) . scrollIntoView ( { block : "end" } ) ;
516+ this . getNextElement ( ) . scrollIntoView ( { block : "end" } ) ;
506517 } else {
507518 this . blurIntent . emit ( "bottom" ) ;
508519 }
@@ -524,7 +535,7 @@ export class DropdownList implements AbstractDropdownView, AfterViewInit, OnDest
524535 */
525536 doClick ( event , item ) {
526537 event . preventDefault ( ) ;
527- if ( ! item . disabled ) {
538+ if ( item && ! item . disabled ) {
528539 this . list . nativeElement . focus ( ) ;
529540 if ( this . type === "single" ) {
530541 item . selected = true ;
0 commit comments