Angular 2+ elegant way to intercept Command+S

Viewed 6858

Trying to implement a shortcut key combination for Command+S to save a form.

I've read this - https://angular.io/guide/user-input, but it does not say anything about meta or command.

Tried surrounding the form with:

<div
  (keyup.command.s)="save()"
  (keyup.command.u)="save()"
  (keyup.control.u)="save()"
  (keyup.control.s)="save()"
  (keyup.meta.u)="save()"
>

Of those, only control.u and control.s worked.

With all the power and cross-browser capabilities of Angular 2+, I was hoping that this is somehow handled in an elegant way, using (keyup...).

And for sure many Angular Devs use Macs :).

I've also read How does one capture a Mac's command key via JavaScript? and http://unixpapa.com/js/key.html but still hoping for Angular elegant solution instead of fighting with browser-specific stuff...

3 Answers

Global listener, non-deprecated answer:

@HostListener('window:keydown', ['$event'])
onKeyDown(event: KeyboardEvent) {
    if ((event.metaKey || event.ctrlKey) && event.key === 's') {
        this.save();
        event.preventDefault();
    }
}
  1. The methods preventDefault() and stopPropagation() and so on did not work for me (using current Chrome), so i had to go multiple keys: ctrl+shift+s
  2. When defining the event handler in my component, it only worked for this subsite and only if some form inputs were in focus, so i had to add the listener at another place.
  3. I compressed the multiple functions, since i do not care about which environment the hotkey gets called, i want to save my object.
ngOnInit() {   
  document.body.addEventListener("keydown", event => {
    let charCode = String.fromCharCode(event.which).toLowerCase();
    switch (((navigator.platform.match('Mac') && event.metaKey) || event.ctrlKey) && event.shiftKey && charCode === 's') {
      case true: {
        this.saveArticle(); //whatever your usecase is
        break;
      }
    }
  });
}
Related