6

I want to use tab key to perform some logic but not actually change the focus. According to this answer's comments I can use false in my markup or preventDefault() in the method. I have both like this.

onKey(event: KeyboardEvent) { 
  event.preventDefault();
  if(event.key = "Tab") { this.update.emit(this.config); }
}

<input #input
   title="{{config|json}}"
   value="{{config.value}}"
   (keyup)="onKey($event)"
   (keydown.Tab)="onKey($event);false;">

Still, it gets an extra jump when I hit tab key. When I tried the very same logic but based on other keys (e.g. "a" or "enter"), the behavior is as expected, so I conclude that the logic is correct. For some reason, by tab is unruly and propagates the event as if I want to tab twice.

Am I handling tab key up incorrectly? Not sure what to google for other than what I already have.

Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • This doesn't really answer your question, but I would be wary of changing the tab functionality since it could throw some accessibility features out of wack and cause unexpected behavior for folks with disabilities. – Pytth Apr 17 '19 at 16:53
  • @Pytth Agreed. This particular case is an application for a limited and secluded number of users who think that Excel is the best tool ever so they demand to be able to tab to the next cell. :) – Konrad Viltersten Apr 17 '19 at 16:55
  • I don't see the behavior you describe. I've removed all the items which are undefined: https://stackblitz.com/edit/angular-11zsgl?embed=1&file=src/app/app.component.ts – jcuypers Apr 17 '19 at 16:59
  • @jcuypers I confirm. There's still an issue, though. When I add a second input box and try to programmatically focus on it, I can set it's value but the focus stays in the initial one. Please view [the sample](https://stackblitz.com/edit/angular-qesnun). – Konrad Viltersten Apr 17 '19 at 17:18
  • @KonradViltersten: it works though: https://stackblitz.com/edit/angular-gbuwma?embed=1&file=src/app/app.component.ts. you have used `setFocus()` instead of `focus()`. – jcuypers Apr 17 '19 at 17:27
  • @jcuypers I can confirm that too. In fact, I can see that my diagnostics are flawed. Your comment is the correct answer. Please repost it as such so I can accept it. (Still, sadly, the issue in my application remains. Somehow, the tab key manages to emit itself twice to the parent. Damn if I know why...) – Konrad Viltersten Apr 17 '19 at 17:37
  • @KonradViltersten based on the stackblitzes we exchanged I guess you removed (keyup) from your original code? if not, it would explain the double emits. – jcuypers Apr 17 '19 at 18:37
  • @jcuypers Hats off to you. I've found that was the root cause to the issue before I saw your suggestion but I have a running system to horse around in and test stuff. You only have my description to go on. I'm impressed. Good call, mate. – Konrad Viltersten Apr 17 '19 at 21:57
  • @KonradViltersten. Thanks just trying to be helpful. Luckily I have been gifted great/fast troubleshooting skill at birth :) – jcuypers Apr 18 '19 at 05:14

2 Answers2

3

Try to use this code:

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

@HostListener('document:keydown.tab', ['$event'])
onKeydownHandler(event: KeyboardEvent) {
    event.preventDefault();
}
Dmitry Grinko
  • 13,806
  • 14
  • 62
  • 86
2

Extract from the stackblitz : https://stackblitz.com/edit/angular-gbuwma?embed=1&file=src/app/app.component.ts

ts

import { Component, ViewChild, ElementRef,ChangeDetectorRef } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  constructor(private changeDetector: ChangeDetectorRef) { }


  @ViewChild("input2") input2: ElementRef;

  onKey(event: KeyboardEvent) {
    event.preventDefault();
    if (event.key === "Tab") {
        console.log('ole... tab');
        this.input2.nativeElement.value = "aha";
        this.changeDetector.detectChanges();
        this.input2.nativeElement.focus();
    }

  }

}

html

<input #input
   title=""
   value=""
   (keydown.Tab)="onKey($event);false;">
 - - - 
   <input #input2
   title=""
   value=""
   (keydown.Tab)="onKey($event);false;">
jcuypers
  • 1,774
  • 2
  • 14
  • 23