This context discusses best practices and pitfalls for implementing keyboard listeners in Angular applications.
Abstract
The article provides five case studies on handling keyboard listeners in Angular apps, focusing on reacting to users via keyboard events or shortcuts. The first case study demonstrates two ways to open a dialog when a user presses F2 on an input field, highlighting the importance of choosing the most optimized approach. The second case study discusses the pitfalls of using a listener for any click on the whole document, while the third case study shows how to allow users to execute a search method by clicking on a search button or pressing the Enter key. The fourth case study emphasizes the need to consider user experience when implementing keyboard listeners, and the fifth case study reminds developers to consider different devices when adding keyboard shortcuts.
Opinions
Developers should optimize keyboard listeners to avoid performance issues in users' browsers or flattening their phone batteries.
Choosing the most optimized approach for implementing keyboard listeners is crucial.
Developers should avoid using a listener for any click on the whole document to prevent unnecessary method execution.
Allowing users to execute a search method by clicking on a search button or pressing the Enter key is a good practice.
Developers should consider user experience when implementing keyboard listeners.
Developers should consider different devices when adding keyboard shortcuts.
Software Engineering
Accessibility in Angular–Good Practices and Pitfalls
As developers, we love to use the keyboard in our daily coding life. It makes things easier and quicker to perform than using the mouse. Yet we are not alone in this love; many end-users of the applications we’re implementing love to do it too. Designing an app to be more accessible generally improves the user experience. The only problem here is that knowing how to use the keyboard is much simpler for us than knowing how to implement a feature accessible by pressing some keys from the keyboard.
Whenever you add an event listener to your code, you should do it in an optimized way to avoid sucking performance from users’ browsers or flatten their little phone batteries.
In today’s article, I will focus on reacting to users via keyboard events or shortcuts. I will take five real-life examples of handling keyboard listeners in an Angular app. Let’s get started.
Case Study 1
Let’s say you have an input field in your component and you want to open a dialog when the user presses F2. You can do it in two ways.
With the first one, we have a keydown.F2 listener just for the input field. With the second one, we have a keydown.F2 listener for the whole component that will be executed whenever F2 is pressed — even when the focus is outside the input field. I personally prefer the first alternative.
Pitfall
If you use those two options together:
(keydown.F2)=”onF2KeyPress($event)”
In the input field and
@HostListener(‘keydown.F2’, [‘$event’])
Above the method onF2KeyPress(), your logic will be executed twice. In this case, the dialog will be opened twice and you may not notice it until you see that you can close the dialog only if you click on the close button twice.
Case Study 2
Let’s say you have a formArray and you need to save the previously edited formGroup whenever the user clicks on another formGroup. To achieve this goal, you have created the following method:
This method is a listener for any click on the whole document (the HTML view in front of you) and not only a listener for a click in the form area. If the user opens a dialog from the formArray and clicks on it, the onClick() and this.saveItem() methods will be executed even when they’re not required (since the user is still working in the dialog).
This case could be worse if the saveItem() method calls some service methods and sends some REST API requests to execute something in the back end.
Case Study 3
Let’s say you have a form with some fields to enter some search criteria and you want to offer the user the possibility to execute the search() method by a click on the search button or by pressing the Enter key. To achieve this, you have implemented your HTML code as follow:
And your TypeScript:
search() {
this.service.search(this.form);
}
Can you guess what is wrong here?
There are two problems:
First, the search() method will be executed whenever a keyup event is emitted (even when the user presses Tab, shift, F3, …) and not only when Enter is pressed. To fix it, the first line in the HTML code must be adjusted as follows:
Secondly, you want to allow the call to search only when the form is valid and touched. This is implemented correctly by disabling the search button ([disabled]="form.invalid ||form.untouched") but violated by calling search() after pressing Enter. The following could be a workaround for this bug:
You have implemented a dialog with a form to create or update some items. After entering the data, the user can click on the save button or press Enter to send a save request to the REST API. After sending a save request, the dialog should be closed automatically.
Can you guess if this will work as expected?
Well, what if the form contains a dropdown field and the user wants to select an option from it by using their keyboard as follows?
To open the options list in the dropdown, the user presses Enter after setting the focus in that field.
Then they use arrow-down/arrow-up to navigate to the wanted option.
Then they press Enter to select that option.
Your end-user will be frustrated when they notice that whenever they press Enter, the dialog disappears while they wanted to continue editing before closing it.
How can you fix that?
You can use another keyboard listener to call the save() method. control.s could be an alternative:
In your web app, there is a view with multiple action buttons that should be accessible with the keyboard. For each action button, you have added a different shortcut listener: alt+e, alt+r, alt+o, etc.
What’s wrong with this solution?
End-users could have different devices. Those shortcuts will not be useful for a Mac user. As a fix, you can add listeners for those shortcuts: cmd+e, cmd+r, cmd+o, etc.
Takeaways
Let’s summarize what we just learned:
Limit and specify the areas that have to listen to some keyboard events.
Select your keyboard listeners thoughtfully and try to imagine their possible side effects and the cases where they will not work.
Don’t forget that your end-users have different devices. When you add keyboard shortcuts, they must be useful for all possible end-users (PC, Mac, etc).
Thanks for reading. If you have any questions, feel free to leave a comment.