30

How can I handle a Tab keypress event in Angular 2?

I took this from the Angular docs to get the keyCode. It works well when I press the other keys, but when I press Tab nothing happens.

import { Component } from '@angular/core';

@Component({
 selector: 'my-app',
 template: `<input (keyup)="onKey($event)">
            <p>{{values}}</p>`
})

export class AppComponent {
  values = '';
  onKey(event: any) { 
  this.values += event.keyCode+ ' | ';
  }
}

Also, is this the correct way to do it in Angular 2?

<input ng-keydown="($event.keyCode == 9) && 
       signal('something')" />
Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
freeNinja
  • 365
  • 1
  • 4
  • 11

3 Answers3

66
 <input (keydown.Tab)="onKey($event)">
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • You need to add `tabundex="0"` so the div can receive the focus and keyboard events. – Günter Zöchbauer Feb 15 '17 at 04:23
  • Thank you a lot! that works for me. Is there a way to prevent the default events of Tab. event.preventDefault() ? – freeNinja Feb 15 '17 at 04:26
  • 1
    I don't really understsnd the comment but `preventDefault()` is called when `false` is returned like ``. Alternatively `onKey()` can retzrn `false` or call `event.preventDefault()` – Günter Zöchbauer Feb 15 '17 at 05:00
  • When I press Tab, at first the focus is on the whole browser window then the browser tab then the page and then the div and finally it executes what should be done on the div. I want to ignore all this and execute my onKey fuction when I press Tab for the first time. – freeNinja Feb 15 '17 at 17:08
  • You need to ensure that the element has the focus from the beginning, then `onKey()` should executed on the first `tab` press. You set the focus by calling `element.focus()`. http://stackoverflow.com/a/34573219/217408 shows a directive that does that (using the `Renderer`) – Günter Zöchbauer Feb 15 '17 at 17:11
  • Would you say that the syntax of `(eventname.SpecificThing)=foo()` is a hacky work-around for special cases when the required effect can't be achieved in other ways (a sort of last resource to make stuff work)? Or should we consider using it when e.g. the only event that needs handling is pressing a certain key, like `(keyup.X)=reactToX()` (in a weird scenario where we only do stuff when the user types "x")? – Konrad Viltersten Apr 06 '19 at 21:48
  • @KonradViltersten only the later – Günter Zöchbauer Apr 07 '19 at 07:29
4
<input (keypress)="someFunction($event.target.value)"/>
Yoav Schniederman
  • 5,253
  • 3
  • 28
  • 32
4

I was having a similar problem. I initially tried using $event in the template, but after some reading here, it seems passing $event isn't something the Angular team encourages (see the link for detail). They recommend using template reference variables. This was fine until I tried using tab and I ended up getting what @freeNinja was getting; tab would work but then direct focus to the top of the page. @ Günter Zöchbauer answer in the comments above worked for me. Adding false after the method call stopped the focus from being transferred. (keydown.tab)="saveEntry(i, newCost.value); false

Hodglem
  • 614
  • 9
  • 17