# Keyboard Utilities

## Overview

Keyboard interactions are essential for creating user-friendly, efficient, and accessible web applications. Servoy provides two distinct utilities to manage keyboard inputs effectively:

* [Shortcuts](#shortcuts): With the [plugins.window.createShortcut](https://docs.servoy.com/reference/servoyextensions/browser-plugins/servoy-window-plugin#createshortcut-shortcut-callback-contextfilter-arguments-consumeevent) API, developers can define global or context-specific keyboard shortcuts to execute predefined actions. This allows users to perform tasks quickly, such as creating records, navigating forms, or triggering frequently used operations.
* [Keystroke Handling](#keystroke-handling): Using the [svyKeyListener](https://docs.servoy.com/reference/servoyextensions/browser-plugins/key-listener#key-listener-ref) service, developers can capture and respond to specific key events within designated components. This utility offers advanced features like dynamic listener registration, delayed execution, and input transformation for enhanced functionality.

**Benefits of Keyboard Utilities**:

* Improved Workflow Efficiency: Users can perform repetitive tasks more quickly through intuitive shortcuts and keystroke handling.
* Enhanced Interactivity: Developers can design responsive applications that react to user input in real time.
* Accessibility Support: Keyboard interactions ensure seamless navigation and functionality for users relying on assistive technologies.
* Customizable Behavior: Both utilities allow for flexible configuration, enabling tailored keyboard-driven features across different application contexts.

These utilities allow developers to implement efficient navigation, quick actions, and advanced interactivity for users.

## Shortcuts

<div align="left"><figure><img src="https://3933488479-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjpWd52BKwABWxF2lScUK%2Fuploads%2Fgit-blob-24d5b270a2e44bd186872290f72bf2aff3a27281%2Fkeyshortcut-demo.gif?alt=media" alt=""><figcaption><p>Shortcut demo</p></figcaption></figure></div>

Shortcuts allow users to quickly trigger specific actions using predefined key combinations. Using the [plugins.window.createShortcut](https://docs.servoy.com/reference/servoyextensions/browser-plugins/servoy-window-plugin#createshortcut-shortcut-callback-contextfilter-arguments-consumeevent) API, developers can:

* **Define Global Shortcuts**: These work across the application, independent of the current form or context.
* **Set Context-Specific Shortcuts**: Limit shortcuts to specific forms or components for better control and focus.
* **Prevent Default Browser Behavior**: Configure shortcuts to consume events and prevent clashes with existing browser or OS shortcuts.

Typical use cases include:

* Creating new records.
* Navigating between forms or tabs.
* Triggering frequently used operations, such as saving data or opening dialogs.

By enabling shortcuts, developers can significantly improve the speed and accessibility of application workflows.

### Example: Keyboard Shortcut to Create a New Record

The [plugins.window.createShortcut](https://docs.servoy.com/reference/servoyextensions/browser-plugins/servoy-window-plugin#createshortcut-shortcut-callback-contextfilter-arguments-consumeevent) API enables the creation of global or form-specific shortcuts, providing quick access to frequently used operations.

```javascript
function onShow(firstShow, event) {
    // Create a global keyboard shortcut for "Shift+N" to create a new record.
    plugins.window.createShortcut(
        'shift N', 
        createNewRecord, 
        null, // No specific context; global shortcut
        null, // No arguments
        true  // Consume the event to prevent default browser behavior
    );
}

/**
 * Callback function triggered by the shortcut.
 */
function createNewRecord(event) {
    foundset.newRecord();
    plugins.webnotificationsToastr.success(
       "New record created!", 
       "Success", 
       { positionClass: "toast-top-right", timeOut: 3000 }
    );
}
```

Explanation:

* Shortcut Creation: \* The [`plugins.window.createShortcut`](https://docs.servoy.com/reference/servoyextensions/browser-plugins/servoy-window-plugin#createshortcut-shortcut-callback-contextfilter-arguments-consumeevent) method is used to define the `Shift+N` shortcut. \* This shortcut is global (`contextFilter: null`) and works across the application.
* Consume Event: \* The `consumeEvent: true` parameter ensures that the browser does not execute any default behavior associated with the `Shift+N` combination.
* Callback Function: \* The `createNewRecord` function is executed when the shortcut is pressed. \* Actions Performed: \* `foundset.newRecord()`: Creates a new record in the current foundset. \* `plugins.webnotificationsToastr.success`: Displays a success notification in the top-right corner of the screen with the message "New record created!" and a timeout of 3 seconds.

## Keystroke Handling

<div align="left"><figure><img src="https://3933488479-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjpWd52BKwABWxF2lScUK%2Fuploads%2Fgit-blob-6a990beb949f8660319f3c2029f7ef3bf485bf9b%2Fkeylistener-demo.gif?alt=media" alt=""><figcaption><p>Keystroke Handling demo</p></figcaption></figure></div>

Keystroke handling provides fine-grained control over keyboard input within specific components. The [svyKeyListener](https://docs.servoy.com/reference/servoyextensions/browser-plugins/key-listener#key-listener-ref) service allows developers to listen for and respond to key events in designated input fields or components. Key features include:

* **Dynamic Listeners**: Attach or remove listeners dynamically during runtime based on application needs.
* **Customizable Delay**: Debounce events using the delay parameter to ensure efficient handling of rapid key presses.
* **Input Transformation**: Use regular expressions to modify input values in real time, ensuring clean and consistent data.
* **Event-Based Actions**: Trigger server-side methods or logic based on user input.

This level of control is especially useful for:

* Implementing real-time search functionality.
* Validating and formatting input fields.
* Enhancing forms with interactive keyboard-driven behavior.

{% hint style="info" %}
To be able to use Keystroke Handling, the **Key Listener** package must be added from Services section of [Servoy Package Manager](https://docs.servoy.com/reference/servoy-developer/package-manager#package-manager). It can be accessed by code using `plugins.webnotificationsNative`.
{% endhint %}

### Example: Using Key Listener for Real-Time Search

The [svyKeyListener](https://docs.servoy.com/reference/servoyextensions/browser-plugins/key-listener#key-listener-ref) service allows developers to monitor specific keystrokes in components with the `keylistener` attribute. This service provides advanced features like delay handling and input modification using regular expressions.

This example demonstrates how to use a key listener to implement a real-time search feature in an input box with the keylistener attribute value `country_search`. The listener filters the records in the foundset based on the user's input.

On the component(s) you want to register the listener, you need to add a keylistener attribute. Let's assume we add the keylistener attribute with the value `country_search` to be used as a callback key:

<div align="left"><figure><img src="https://3933488479-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjpWd52BKwABWxF2lScUK%2Fuploads%2Fgit-blob-9de2657200f20de6689cb778d8b4ea5c0055f24e%2Fkeylistener-attribute.jpg?alt=media" alt=""><figcaption><p>keylistener attribute</p></figcaption></figure></div>

Then, for instance in the `onShow` method of the form, you need to associate that callback key (`country_search`) to a function (`onSearchKeyPress`):

```javascript
/**
 * Add Key Listener on form show.
 */
function onShow(firstShow, event) {
    // Add a key listener to monitor keystrokes in the input box with "keylistener" attribute value "country_search".
    plugins.keyListener.addKeyListener('country_search', onSearchKeyPress);
}

/**
 * Key listener callback function.
 */
function onSearchKeyPress(value, event, keyCode, altKey, ctrlKey, shiftKey, capsLock) {
    if (value){
	if(foundset.find()){  // Enter find mode
	shipcountry = '#'+value+'%'; // Assign a search criteria
	foundset.search(); // Execute the query and load the records
	}
    }
}

/**
 * Remove Key Listener on form hide.
 */
function onHide(event) {
    if (plugins.keyListener.removeKeyListener('country_search')) {
        application.output("Key listener for 'country_search' removed.");
    }
}
```

Explanation:

* **Adding the Key Listener**: \* The [`plugins.keyListener.addKeyListener`](https://docs.servoy.com/reference/servoyextensions/browser-plugins/key-listener#addkeylistener) method is called in the `onShow` function. \* It associates the `keylistener` attribute value `country_search` with the callback function `onSearchKeyPress`. \* This listener is triggered whenever the user types in the input field.
* **Keylistener Attribute**: \* The `country_search` key must match the keylistener attribute value set on the input field in the form's designer.
* **Callback Function (`onSearchKeyPress`)**: \* This function is executed when a keystroke is detected in the input box. \* Behavior: \* If the input (`value`) is not empty, the method: \* Enters find mode using `foundset.find()`. \* Assigns a search criterion to the `shipcountry` field, allowing partial matches (`#` for case-insensitive search, `%` as a wildcard). \* Executes the search using `foundset.search()`, filtering the foundset records based on the input value.
* **Removing the Key Listener**: \* The [`plugins.keyListener.removeKeyListener`](https://docs.servoy.com/reference/servoyextensions/browser-plugins/key-listener#removekeylistener) method is called in the `onHide` function. \* This ensures that the listener is unregistered when the form is hidden, releasing resources and preventing unwanted behavior. \* A confirmation message is logged when the listener is successfully removed.
