63 lines
2.2 KiB
Markdown
63 lines
2.2 KiB
Markdown
---
|
|
title: Form Autofocusing
|
|
description: Autofocusing to Form Fields - Common Use Cases
|
|
date: 2020-02-25
|
|
tags:
|
|
- Tech
|
|
- A11y
|
|
---
|
|
|
|
Controlling form focusing is always a "it depends" kind of situation. However, we can often times make intelligent decisions rather than leave the user hanging.
|
|
|
|
Imagine a common scenario. I have a pastry shop app and I click "New Donut". A form pops up with inputs for attributes such as the Nickname, Toppings, and Dough type for this donut recipe. I begin typing... oops! I have to tab through every interactable element on the page until I find this newly appeared form. Eep!
|
|
|
|
In such a scenario it makes sense to write reusable components for our form elements. Consider the following:
|
|
|
|
{% raw %}
|
|
```html
|
|
<button>New Donut</button>
|
|
|
|
{{#if this.creatingNewDonut}}
|
|
<UiForm
|
|
@shouldAutofocus={{true}}
|
|
@submit={{this.submitHandler}}>
|
|
<UiLabel>
|
|
Nickname
|
|
<UiInput />
|
|
</UiLabel>
|
|
<UiLabel>
|
|
Toppings
|
|
<UiInput />
|
|
</UiLabel>
|
|
<UiLabel>
|
|
Dough Type
|
|
<UiInput />
|
|
</UiLabel>
|
|
</UiForm>
|
|
{{/if}}
|
|
```
|
|
{% endraw %}
|
|
|
|
_The above code example is written in htmlbars (handlebars for Ember) but it's a generalized example that could apply to any framework._
|
|
|
|
Now in our `UiForm` component we can write some code into your framework's render hook like so:
|
|
|
|
```js
|
|
let focusableQuerySuffix = ':not([readonly]):not([disabled]):not([tabindex="-1"])';
|
|
let focusableQueries = [
|
|
`input${focusableQuerySuffix}`,
|
|
`textarea${focusableQuerySuffix}`,
|
|
`select${focusableQuerySuffix}`,
|
|
];
|
|
let element = this.element.querySelector(focusableQueries.join(',')); // this.element will vary for your framework of choice, replace it with however you target your component's dom element
|
|
if (!element) return;
|
|
|
|
element.focus();
|
|
```
|
|
|
|
Focusing an element is the easy part, simply call `.focus()` on any dom element. Finding which dom element to query is the tricky part. Generally avoiding anything with a `readonly`, `disabled` or `tabindex=-1` attribute is safe so long as you follow html semantics carefull in your application.
|
|
|
|
This could be expanded to support radio buttons, button elements and other interactable dom elements should you so choose.
|
|
|
|
Focus responsibly!
|
|
|