11

How can I bind a keyevent listener on the document instead of an specific inputfield in Angular 2 using RC5?

For example:

I Know this "bind it to an element"

<input (keypress)="onKeyDown($event)" [(ngModel)]="something" type="text">

How can I bind it to the document for example

<div (keypress)="onKeyDown($event)"> <input /> ... </div>
Sangwin Gawande
  • 6,656
  • 8
  • 46
  • 60
Emanuel Weinsjö
  • 411
  • 1
  • 5
  • 15

2 Answers2

23
@HostListener('window:keydown', ['$event'])
onKeyDown(event) {
  ...
}

You can also do

<div (window:keypress)="onKeyDown($event)">

or

<div (document)="onKeyDown($event)">

Declarative filtering like

<div (window:keydown.alt.a)="onKeyDown($event)">

is currently not supported for global listeners

See also https://github.com/angular/angular/issues/7308

Frederik Struck-Schøning
  • 12,471
  • 8
  • 59
  • 64
Günter Zöchbauer
  • 558,509
  • 191
  • 1,911
  • 1,506
  • can you please guide how to get hold of long press backspace key? – Naveed Ahmed May 11 '17 at 15:14
  • I guess observables are a good bet for this use case. Listen for keydown and then for keyup and get the delay between down and up. I'm not used to rxjs operators therefore can't give you more concrete advice (I'm working only with Dart) http://pragmatic-coder.net/click-and-longclick-with-rxjs/, http://stackoverflow.com/questions/19424429/detecting-multitouch-longpress-event-using-rxjs might give you some ideas. I also found https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/doc/operators/keypress.md but it's for rxjs4 and Angular uses rxjs5. – Günter Zöchbauer May 11 '17 at 15:18
  • Thank you for your reply, just came across this , but its also in Dart http://stackoverflow.com/questions/34715315/how-do-i-make-a-stream-of-keyboardevents-that-is-triggered-on-long-pressing-the – Naveed Ahmed May 11 '17 at 15:26
  • LOL, didn't remember at all I did this and I didn't know rxjs at all back then as well. Shouldn't be too hard to port to TS, but I'm sure there is a much more elegant solution using rxjs. – Günter Zöchbauer May 11 '17 at 15:32
  • Yes it was answered by you. I tried to port it to ts but seems some features are available in dart only like Duration, Timer etc. – Naveed Ahmed May 11 '17 at 15:34
  • In TS just use `number` with millisecond values instead of `Duration`. Instead of `new Timer()` use `setTimeout()` – Günter Zöchbauer May 11 '17 at 15:40
  • Getting error on this line this.longpress.add(this._startEvent); "Property 'add' does not exist on type 'EventEmitter'" any idea? – Naveed Ahmed May 11 '17 at 16:06
  • It's `emit` in TS – Günter Zöchbauer May 11 '17 at 16:18
  • Yes, I also tried that and it worked. BTW I have updated that question with typescript version. Thanks for the help :) – Naveed Ahmed May 11 '17 at 16:41
  • Great, I planned to ask you to do that. Glad to hear you could make it work :-) – Günter Zöchbauer May 11 '17 at 16:46
  • There seems to be a little error, setTimeout is firing for all keys only only for long pressed keys :/ – Naveed Ahmed May 11 '17 at 16:51
  • I logged the event in keyEventHandler function of directive and its returning key: "Unidentified" for all keys. Any idea? BTW I am trying it in Ionic app – Naveed Ahmed May 11 '17 at 17:02
  • 1
    Small 2020 update, declarative filtering as given in the answer, `
    ` does work now. In the [same Github issue linked](https://github.com/angular/angular/issues/7308#issuecomment-262727498), there's a comment to close made on Nov 24, 2016. The next major Angular release was 4.0.0 in [March 23, 2017](http://blog.angularjs.org/2017/03/angular-400-now-available.html), so any version beyond that should be good to go.
    – OSH Jul 28 '20 at 16:23
  • 1
    I've made the above comment instead of editing because I couldn't find a commit to cite, or any direct references to the feature in the Angular docs or any release notes. I wasn't sure if the [Github issue comment](https://github.com/angular/angular/issues/7308#issuecomment-262727498) is sufficient evidence to justify the edit. – OSH Jul 28 '20 at 16:26
  • @OSH I'd accept such an edit. Thanks for the update! – Günter Zöchbauer Jul 28 '20 at 16:30
0

You can also use rxjs for this

fromEvent<KeyboardEvent>(document, 'keydown')
  .pipe(...)
  .subscribe()

See: https://www.learnrxjs.io/learn-rxjs/operators/creation/fromevent

  • 1
    Consider editing your question to include an explanation as to how your answer addresses the question. – JohnH May 06 '21 at 14:17