Block normal keyboard key behavior with JavaScript in OutSystems

Ricardo Pereira
ITNEXT
Published in
5 min readApr 26, 2024

--

Sometimes, in our applications, we need to block or prohibit behaviors triggered by keyboard keys (for example, preventing the ‘Enter’ key from triggering the action associated with a default button or performing a line change).

This type of functionality can be obtained using a few lines of JavaScript code, and to do so, we have to know the codes for each of the keys we want to block.

The example that will be demonstrated is a generic abstraction that can receive any code referring to a key abstracted into a static entity that will be added to the JavaScript code to block the desired key. This way, development becomes much more comprehensive and generic, avoiding similar development for more than one key.

In this way, we start by obtaining the list of keyboard key codes.

For the example, we will place codes for 3 keys in the entity: Enter, Space and Backspace (feel free to add more keys to the entity in order to manage your case in the best way).

This way, we have the following data:

Now, we create the module to handle our development. Knowing that we are dealing with business-agnostic functionalities and that they must be made generally available, it is advisable to implement them in a module of a Foundation layer application. The example module will be called ‘KeyboardUtils_FS’ and may contain keyboard-related features and will be of type ‘Library’:

Fig 1 — Creation of a ‘Library’ module to implement the mentioned functionalities

The next step is to create the static entity that will support the storage of the keys we need. To do this, we create an entity with the following attributes:
- Identifier — Mandatory, Integer: Identifier used for the respective key for Win32API virtual codes;
- Name — Mandatory, Text (length 10): Name used for the respective key for Win32API virtual codes;
- Code — Mandatory, Text (length 10): Code used for the key by ASCII;
- IsActive — Mandatory, Boolean: Defines whether it is a usable key or not;

The static entity must be defined as public so that it can be consumed by other modules:

Fig 2 — Creation of a static entity to store the keys

Next, the keyboard key records are loaded into the entity:

Fig 3 — Keyboard key data loaded into the static entity

The next step is to create a Server Action to obtain the registration of a specific keyboard key based on the identifier defined in the input.

NOTE: This part of the code could be carried out directly in a Client Action, but we must abstract it on the server side to be able to insert any type of validation that we deem necessary in a safer and more effective way.

This Server Action (not public, as this functionality will later be abstracted into a public Client Action) must use the native action of the static entity ‘GetKeyBoardKey’ to obtain the registration of the desired key, receiving in its input the value inserted in the input from Server Action. In order to ensure that we only return valid records, after obtaining the record by the static entity’s native action, we must validate with an ‘If’ if the ‘IsActive’ attribute of the returned record is =True. If yes, we map the output of the native action to the output variable of the Server Action (of type ‘KeyboardKey’), if it is =False, we leave the output variable empty:

Fig 4 — Definition of Server Action to obtain keybord key registration based on input (id)

To actually obtain the functionality and be able to make it available to any consumer who needs it, a Client Action is created, defined as public (the JavaScript code that runs must be on the browser side) that receives as input the ‘KeyboardKeyId’ related to the key of the keyboard we want to block. This Client Action consumes the previously implemented Server Action to obtain the necessary KeyboardKey registration, and for this purpose, we must map the Client Action input to the Server Action input:

Fig 5 — Using the Server Action ‘GetKeyboardValuesById’ to obtain the key record to be blocked

We must then check whether there is any record returned in order to avoid invoking JavaScript code without content for the expected key. If there is no record returned, we must issue a message in the “Message” output informing what happened, and we must also assign the value “False” to the “Success” output:

Fig 6 — Checking the return of an empty register and respective parameterization of the outputs in case of failure

Once the Server Action record is returned, we can then define the JavaScript code. This same code will feed on the three relevant attributes of the KeyboardKey record, that is, the JavaScript node will have defined three input parameters: KeyCode, KeyIdentifier and KeyName.

Then, defining the JavaScript code as necessary and in order to obtain the values of the input parameters as necessary, we are left with the following:

window.addEventListener('keydown',function(e) {
if (e.keyIdentifier==$parameters.KeyCode || e.keyIdentifier==$parameters.KeyName || e.keyCode ==$parameters.KeyIdentifier ) {
e.preventDefault();
return false;
}
},true);

NOTE: The KeyCode is marked by the JavaScript Node as ‘Deprecated’, which is used to check for backward compatibility in browser versions and to ensure that all forms of verification are used.

The JavaScript node looks like this:

Fig 7 — JavaScript code that will result in blocking the key inserted in the Client Action input

After defining the JavaScript node, we define the ‘Success’ output variable with the value ‘True’ and leave the “Message” output variable empty, as we do not have relevant information to transmit to consumers in the success scenario:

Fig 8 — Definition of the output for the success case

Now, we publish and test (if it is a new module, it is recommended to do ‘Remove Unused Dependencies’ to make the module as compact and concise as possible).

And it’s ready! We can test and verify functionality.

This example shows how we can apply this functionality in a simple and generic way, and if we have more keyboard keys that we want to block their native behavior, simply add a record with the necessary values for each of the attributes in order for it to work correctly.

If you want to check this example implemented, you can download the following Forge component: https://www.outsystems.com/forge/component-overview/18632/keyboard-utils-o11/0

As always, I hope this content helps someone on their OutSystems technology journey!

--

--

Passionate about software development, started my journey in Outsystems in 2016, getting completely addicted to the platform.