Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Focus text input with keypress in Angular 2 without adding keypress value

I'm adding keyboard shortcuts in my application, and one of those is Shift + F which triggers the focus method on a specific input e.g. my search field.

The input-element can exist anywhere in the component tree so my approach is to use a Service with an EventEmitter and a Directive which listen to it.

SomeComponent

@Component({ .. })
export class SomeComponent {
  @HostListener('document:keypress', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    if (event.shiftKey) {
      let key = event.key;
      if (key === 'F') {
        this.focusService.focus('mySearchBox');
      }
    }
  }

  constructor(private focusService: FocusService) { }
}

Somewhere in the html i apply a focus directive.

<input focus="mySearchBox">

FocusDirective

@Directive({
    selector: '[focus]'
})
export class FocusDirective implements AfterViewInit {
    @Input() focus: string;

    constructor(
        private elementRef: ElementRef,
        private focusService: FocusService) { }

    ngAfterViewInit() {
        this.focusService.focusSource.subscribe(res => {
            this.setFocus(res);
        });
    }

    setFocus(item: string) {
        // I use strings to match the call with the input
        if (this.focus === item) { // 'mySearchBox' === 'mySearchBox
            this.elementRef.nativeElement.focus();
            // Do something to avoid the keypress event
        }
    }
}

FocusService

@Injectable()
export class FocusService {
  focusSource = new EventEmitter<string>();

  focus(string) {
    this.focusSource.emit(string);
  }
}

The problem

If I just call focusService.focus('mySearchBox) it works, however since i'm listening for keyboard events, the focus is set and the F is added to the input value.

Can I somehow avoid this behavior (preferably in the directive) so that the input ignores the keypress?

I've tried resetting the value of the input, but the F gets added after the method is finished so there is no use.

like image 928
Jakob Segerslätt Avatar asked Jun 23 '26 06:06

Jakob Segerslätt


1 Answers

Try using preventDefault():

let key = event.key;
if (key === 'F') {
    event.preventDefault();
    this.focusService.focus('mySearchBox');
}

The event.preventDefault() method stops the default action of an element from happening.

Read more about preventDefault() here.

Edit:

You might need to listen to keydown event instead of keypress.

@HostListener('keydown', ['$event'])
like image 173
Stefan Svrkota Avatar answered Jun 24 '26 20:06

Stefan Svrkota



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!