horilla.contrib.keys registers global hotkeys — search, navigation, create actions — with per-user preference storage via API.
This post is Part 24 of 28 in the Horilla CRM Technical Blog series.
What is keyboard shortcuts in Horilla CRM?
Keyboard shortcuts in Horilla CRM enable you to:
- Central shortcut registry
- User override preferences
- Integration with global search
- Module-specific bindings
Browser event handling
The client integration is short_key.js. Its event handling deliberately tracks the Alt key while it is held and combines that state with subsequent key events. This avoids interpreting a plain letter as an application command and supports the Alt-based shortcuts supplied by the default set. It must also avoid firing while the user is entering text in an input, textarea, or editable region; otherwise, a navigation shortcut can destroy an in-progress edit. When adding a binding, verify which keyboard layout and browser reservation applies, because some Alt combinations are consumed by browser menus or operating-system controls before JavaScript sees them.
The browser should obtain the active definitions from the data endpoint rather than embedding a copy in each screen. ShortKeyDataView is a login-protected view that returns JSON intended for that script. Load the script through the shared layout so the event logic is installed once per page. Do not attach it repeatedly after HTMX swaps: duplicated listeners can make one press navigate twice or execute conflicting actions.
document.addEventListener("keydown", (event) => {
if (event.altKey && event.key.toLowerCase() === "l") {
event.preventDefault();
window.location.assign(shortcuts["alt+l"].url);
}
});
The example illustrates the dispatch shape only. Production code should continue to use the app’s short_key.js normalization and fetched data rather than creating a second listener with divergent matching rules.
Default records and user lifecycle
DEFAULT_SHORTCUTS in the keys app supplies the canonical initial shortcut definitions. A user-creation signal copies the predefined entries for a new user, which gives new accounts useful controls without an administrator manually creating each record. That lifecycle behavior matters when adding a default: change DEFAULT_SHORTCUTS for future users and decide separately whether an existing-user migration or an explicit synchronization command is required. Simply changing the Python constant does not rewrite records that already exist.
Keep a distinction between defaults and user configuration. A user’s altered or disabled record should not be silently reset by the create signal, and a custom record should not be overwritten merely because its key combination resembles a default. Any bulk synchronization feature must make that policy explicit, ideally with a preview and an opt-in for overwrites.
if created:
ShortcutKey.objects.bulk_create(
ShortcutKey(user=instance, **shortcut)
for shortcut in DEFAULT_SHORTCUTS
)
Extending shortcuts
Add a shortcut by deciding its stable route, label, key representation, and collision behavior before editing the defaults. Prefer named application URLs, because a route rename will then be caught by URL resolution and tests. Add the definition to DEFAULT_SHORTCUTS, confirm its data shape is accepted by ShortcutKey, and test the user creation path. Then test ShortKeyDataView while authenticated and inspect the API response from ShortcutKeyViewSet; both should expose the same intended definition.
Finally, test the actual keystroke in a regular page, an HTMX-rendered page, a modal, and a text editor. Shortcut support is useful only if it does not interfere with typing, accessibility technologies, or native browser keys. The shortkeys/ namespace, server-side records, Alt-hold behavior, default signal, JSON view, and viewset together form one system; changing just the JavaScript is not a durable shortcut implementation.
Benefits of Keyboard Shortcuts in Horilla CRM
- Power-user productivity
- Accessible navigation without mouse
- Extensible per app
Register shortcuts from your module, and users can discover them in the keyboard shortcuts settings panel.
Continue the series
Previous: Part 23 — How to Implement Dynamic Brand Colors in Horilla CRM with Tailwind CSS
Next: Part 25 — The Ultimate Guide to Calendar Integration in Horilla CRM
More posts are on the Horilla Blogs; share feedback on GitHub.