global-keyboard-shortcuts
Reactive icon

Global Keyboard Shortcuts

Stable version 1.0.0 (Compatible with OutSystems 11)
Uploaded
 on 10 Sep (8 hours ago)
 by 
0.0
 (0 ratings)
global-keyboard-shortcuts

Global Keyboard Shortcuts

Documentation
1.0.0

Global Keyboard Shortcuts

A drop-in block that adds keyboard shortcuts to any OutSystems Reactive Web app. Register Ctrl+S, Esc, /, Ctrl+K — anything you like — and get a single event when the user presses one. Ignores keystrokes while typing in inputs by default, prevents browser defaults (no more "Save Page As" popping up), and cleans itself up on navigation. Pure client-side, no dependencies.


1. Overview

Power users work with keyboards, and every desktop-class app supports shortcuts. Ctrl+S to save, Esc to close a modal, / to focus search, Ctrl+K to open a command palette — these are the small details that make an app feel finished. OutSystems doesn't ship a first-class way to wire them, so most apps just skip them.

This block fixes that. You give it a list of shortcut strings, handle its OnShortcut event, and switch on the shortcut name to run whatever action you want. That's the whole integration.

Key features

  • Register any number of shortcuts as a simple Text list.
  • One OnShortcut(Shortcut) event fires with the matched shortcut string.
  • Ignores typing context by default — shortcuts don't fire while the user is in an input, textarea, or contenteditable, unless you explicitly enable that.
  • Prevents browser defaults so Ctrl+S doesn't trigger "Save Page As," Ctrl+K doesn't open the browser search bar, etc.
  • Modifier keys handled naturally: ctrl, alt, shift, meta (Cmd on Mac).
  • Friendly aliases: esc, space, up, down, left, right.
  • Cleans up its listener on block destroy — no leaked handlers across navigation.
  • No dependencies, no server calls.

2. Compatibility

ItemRequirement
OutSystems versionOutSystems 11 (O11)
App typeReactive Web
DependenciesNone

3. Installation

  1. Install Global Keyboard Shortcuts from the Forge (or the .oap via Service Center).
  2. In Manage Dependencies, select the module and check the KeyboardShortcuts block.
  3. Apply and publish.

4. Where to place the block (important)

For shortcuts to work on every screen of your app, place the KeyboardShortcuts block once on your shared Layout. Because its keydown listener is attached to the document, one instance is all you need — it works from any screen the layout serves.

If you only want shortcuts on a specific screen, place the block on that screen instead. Don't place it multiple times per app; that would just attach and immediately replace the listener, wasting work.


5. Quick start

KeyboardShortcuts
   Shortcuts     = ["ctrl+s", "esc", "/", "ctrl+k"]
   AllowInInputs = False

Handle OnShortcut(Shortcut):
   Switch Shortcut:
      "ctrl+s"  → run SaveDraft action
      "esc"     → close current modal
      "/"       → focus the search input
      "ctrl+k"  → open the command palette

Drop the block, set the list, handle the event with a Switch. The block does the rest.


6. Reference — the KeyboardShortcuts block

InputTypeDefaultDescription
ShortcutsText ListThe shortcuts to react to. Use lowercase (ctrl+s) or your preferred casing — matching is case-insensitive.
AllowInInputsBooleanFalseFire shortcuts even while the user is typing in an input, textarea, or contenteditable. Off by default so / doesn't trigger while typing text.
EventParametersWhen it fires
OnShortcutShortcut (Text)Fires with the exact shortcut string the developer registered, so Switch matching works cleanly.

7. Shortcut string format

Modifiers are joined with +, in any order, followed by the key. Case doesn't matter; whitespace is stripped.

Modifiers: ctrl, alt, shift, meta (meta is Cmd on Mac, Windows key on Windows/Linux).

Keys: any letter, digit, or symbol as it appears on the keyboard: a, s, 1, /, ?, ,, .. Plus these friendly aliases for special keys: esc, space, up, down, left, right.

Examples: ctrl+s, Ctrl+S, shift+/, alt+enter, ctrl+shift+k, esc, /, ?.


8. Typing context (why shortcuts don't fire in inputs)

By default, the block ignores keystrokes when the user's focus is on an input, textarea, select, or contenteditable element. This is intentional — you almost never want / to trigger "focus search" while the user is typing "9/11" into a field, or Esc to close a modal in the middle of editing.

If you do want a shortcut to work even while typing (rare — usually only for Ctrl-modified shortcuts like Ctrl+S), set AllowInInputs = True. Note that this applies to all registered shortcuts, not per-shortcut; per-shortcut control is a candidate for v2 if there's demand.


9. Preventing browser defaults

When a registered shortcut matches, the block calls preventDefault() on the event. This is what stops Ctrl+S from opening "Save Page As," Ctrl+K from opening the browser search bar, and so on. If a shortcut isn't registered, the browser handles it normally — the block doesn't interfere.

If you want a shortcut to fire and let the browser do its thing (rare), don't register it and handle the raw keydown yourself. But almost always, when you register a shortcut you want to own it.


10. Cross-platform tips (Mac vs Windows)

Mac users press Cmd for what Windows users press with Ctrl. This block reports them as separate modifiers (meta on Mac Cmd, ctrl on Windows Ctrl), so if you want a shortcut to work on both, register both:

Shortcuts = ["ctrl+s", "meta+s"]

Handle OnShortcut(Shortcut):
   If Shortcut in ["ctrl+s", "meta+s"] → save

A v2 could add a mod+s alias meaning "Ctrl on Windows, Cmd on Mac" — for now, registering both explicitly is the cross-platform pattern.


11. Troubleshooting / FAQ

The shortcut doesn't fire.Confirm the block is on a screen that's actually loaded (usually the shared Layout). Also check AllowInInputs if you're testing while focused on an input. Most importantly: check the shortcut string exactly matches your registration — "Ctrl+S" and "ctrl+s" both work (case-insensitive), but "Ctrl + S" with spaces also works (whitespace is stripped), while typos like "cntrl+s" won't match.

The shortcut fires but so does the browser action.Confirm the shortcut is actually in your Shortcuts list — the block only prevents the default for registered shortcuts. If the browser's action is still happening for a registered shortcut, another script on the page might be intercepting the event first; check your other JavaScript.

Shortcuts fire twice.The block guards against duplicate listeners internally, but if you placed the block on the Layout and on a specific screen, you'd have two instances. Place it only once per app.

Nothing works after navigating between screens.The block cleans up its listener on destroy and reattaches on the next screen's ready — if you've customized the block's lifecycle actions, verify On Destroy still calls Cleanup and On Ready still calls Setup.

Users on Mac say Cmd+S doesn't work.Mac Cmd is meta, not ctrl. Register both ctrl+s and meta+s (see section 10).


12. Best practices

  • Place the block once on the shared Layout so shortcuts work app-wide.
  • Use a Switch on the Shortcut parameter for clean per-shortcut handling.
  • Keep AllowInInputs = False unless you have a specific need — it's the safer default.
  • For cross-platform apps, register both ctrl+ and meta+ variants of each shortcut.
  • Document your app's shortcuts somewhere visible to users (a help panel, a ? shortcut that opens a shortcut list).
  • Don't overload common browser shortcuts casually — Ctrl+T, Ctrl+W, and Ctrl+N are important to users and shouldn't be hijacked without a strong reason.

13. Version history

VersionNotes
1.0.0Initial release. Register shortcuts as a Text list; OnShortcut event with matched shortcut string; input-context filtering; prevent-default on matched shortcuts; friendly aliases (esc, space, arrows); clean listener teardown on destroy.

14. License

Published on the OutSystems Forge as open, reusable code. Free to use and adapt in your OutSystems projects.