Focused Dropdown Disable Selection via Keyboard

618 Views Asked by At

Is there a way to disable the keyboard support for printable characters, mainly letters?

I want to suppress, that an option gets selected when typing any letter.

I tried something like this, but the problem is, that i have a directive bound to a parent component, that listens for key strokes and does stuff then.

const el = this.dropdown.nativeElement.querySelector('.ui-helper-hidden-accessible');
  el.addEventListener(
    'keydown',
      (event: KeyboardEvent) => {
        event.stopPropagation();
      },
      { capture: true }
    );

Also tried event.preventDefault() and event.returnValue = false which did not help.

2

There are 2 best solutions below

7
Daniel Vágner On

To disable the selection of options in a dropdown via keyboard input, you can use the keydown event and prevent the default behavior when a printable character (letter) is pressed.

Create directive.

import { Directive, ElementRef, HostListener } from '@angular/core';

/**
 * Directive to disable keyboard support for printable characters in a dropdown.
 * Prevents selection of options when typing letters.
 */
@Directive({
  selector: '[appDisableDropdownKeyboard]',
})
export class DisableDropdownKeyboardDirective {
  constructor(private elementRef: ElementRef) {}

  /**
   * Event listener for the 'keydown' event on the host element.
   * Prevents the default behavior for printable characters (letters) and stops event propagation. Not arrow donw, up etc..
   * @param event The keyboard event.
   */
  @HostListener('keydown', ['$event'])
  onKeydown(event: KeyboardEvent) {
    event.stopPropagation();
    const printableCharacters = /[a-zA-Z]/;
    if (printableCharacters.test(event.key)) {
      event.preventDefault();
    }
  }
}

Declare directive in app.module.ts or any of your module

  declarations: [
    DisableDropdownKeyboardDirective,
  ],

And in HTML add directive.

<p-dropdown
  appDisableDropdownKeyboard
  [options]="cities"
  [(ngModel)]="selectedCity2"
  editable="true"
  optionLabel="name"
></p-dropdown>

And edited Your Stackblitz

0
neukoellnjenny On

This is a work-around I found for it

const element = this.dropdown.nativeElement.querySelector('.ui-helper-hidden-accessible');
    element.addEventListener(
      'keydown',
      event => {
        if(event.keyCode == 27 || event.keyCode == 13 || event.key == 'ArrowDown' || event.key == 'ArrowUp') {
          return; 
        }

        if (event.key == 'w' || event.key == 's' || event.key == 'a' || event.key == 'd') {
          this.helperService.subjectAsObservable.next(event.key);
        }

        const printableCharacters = /[a-zA-Z]/;
        if (printableCharacters.test(event.key)) {
          event.stopPropagation();
        } 
      },
      { capture: true }
    );
  }

This way I can subscribe to the observable in my parent component where i listen for the keystrokes which dont bubble now anymore and can invoke my actions i need.

you may wonder why the keys WASD, the reason is I need to navigate a form with them, left/right and up/down.