JamesC
JamesC

Reputation: 496

How to generate a global DOM keyPress event in Angular 5?

This question is specifically for the Angular 5 environment.

After reading anything I could find on the subject, from ElementRef to EventEmitter, I still failed to find the proper (simple?) way to simply trigger a global "Document scope" - 'keyPress' or 'keyDown' event like I'd get by simply pressing the wanted key on my [hardware] keyboard.

So, while it's very easy to intercept such event, I simply don't know how to produce one programmably.

For example: I'd like to have a button that, when I press it, will trigger an event equivalent to pressing the key '2' on my [hardware] keyboard.

How do I do that ? (Code in HTML and TS files please) Thanks for your help.

Upvotes: 0

Views: 1050

Answers (1)

RANJIT PATRA
RANJIT PATRA

Reputation: 864

Approach 1: Using @Inject(DOCUMENT)

Please @Inject(DOCUMENT) in your component, then browser Document will be injected to a angular component.

Then we can call the addEventListener("keydown", hadler_method) on this document scope.

  public key: string;
  public keyCode: number;
  public altKey: boolean;
  public shiftKey: boolean;
  public ctrlKey: boolean;

  constructor(@Inject(DOCUMENT) public doc: Document){
    this.addEventListener();
  }

  addEventListener() {
    this.doc.addEventListener("keydown", this.handleEvent.bind(this))
  }
  handleEvent(event: KeyboardEvent){
    this.key = event.key;
      this.keyCode = event.keyCode;
      this.altKey = event.altKey || false;
      this.shiftKey = event.shiftKey || false;
      this.ctrlKey = event.ctrlKey || false;

      // To stop browser default behaviour
      event.preventDefault();
      // To stop event bubbling
      event.stopPropagation();
  }
  ngOnDestroy() {
    this.doc.removeEventListener("keydown", this.handleEvent);
  }

The complete code of Approach 1 is available in stackblitz.

Approach 2: Using @HostListener()

  @HostListener('document:keydown', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    this.handleEvent(event);
  }

The complete code of Approach 2 is available at stackblitz.


Triggering KeyboardEvent on document scope

triggerEvent(el: HTMLElement | Document | Window, type: string, initOptions = {}){
    let defaultoptions = {
      shiftKey: false,
      altKey: false,
      ctrlKey: false,
      cancelable : true,
      bubbles: true,
    };

    // Create a KeyBoard Event
    let event = new KeyboardEvent(type, Object.assign({}, defaultoptions, initOptions));

    // Dispatch event on "el" scope
    el.dispatchEvent(event);
  }

And we can use following code to call the trigger method.

this.triggerEvent(document, "keydown", {
    key: "a",
    keyCode: 97
});

The Complete code is available on stackblitz.

Upvotes: 4

Related Questions