# ✎ Technique: Autocomplete input controls
**Source**: https://accessibility.huit.harvard.edu/technique-aria-autocomplete
**Parent**: https://accessibility.huit.harvard.edu/custom-widgets-and-controls
Autocomplete widgets can be helpful for accessibility because they can make it easier to enter text by providing suggestions based on the characters initially typed. This particularly helps people who find typing more difficult and people who may be susceptible to spelling mistakes.
Creating an accessible integrated autocomplete widget is a complex process. You need to ensure that screen-reader users are notified when the list of suggestions appears and that they can enter the list and select an option using the keyboard.
One solution is to use an ARIA live region to announce when autocomplete options are available, and to create a `listbox` containing the options that appear as the user types, which is controlled with the up and down arrow keys.
## Example
For this example, we’re manually implementing autocomplete for a “choose your pet” input. To begin with, the markup should look like this:
`<form>`\
`<label for="pets">Choose a pet</label>`\
`<div class="suggestions-container">`\
`<div class="suggestions-help" role="status" aria-live="polite"></div>`\
`<input id="pets" data-suggest type="text" autocomplete="off" aria-autocomplete="list">`\
`<div class="suggestions"></div>`\
`</div>`\
`</form>`
Note the `.suggestions-help` live region and `.suggestions`, which will need to be populated with the `listbox` (where applicable) on the `input` event. Also note `autocomplete="off"`, which suppresses native autocomplete functionality that could get in the way of our custom UI. The ARIA property of `aria-autocomplete="list"` replaces the semantics so that “autocomplete” is announced on focus.
`$('[data-suggest]').on('input', function() {`\
`// handle suggestions here`\
`});`
In the code editor example you’ll see an array of pet types. As the user types, the `input` event listens for changes and compares the entered value to each item in the pets array. If there are matches, the first thing the script does is alert the user using the live region:
`if (!_.isEmpty(suggestions)) {`\
`$('.suggestions-help', scope).text(`\
`'There are '+suggestions.length+' suggestions. Use the up and down arrows to browse.');`\
`}`
This tells the user how many suggestions are available (`suggestions.length`) and—importantly—how to choose from those suggestions. The newly populated `listbox` is made focusable using `tabindex="0",` and it is focused if the user presses the down arrow key. In this state, list’s markup looks like this:
`<div role="listbox" tabindex="0" aria-activedescendant="pets-0">`\
`<div id="pets-0" role="option" tabindex="-1">hamster</div>`\
`<div id="pets-1" role="option" tabindex="-1">hermit crab</div>`\
`<div id="pets-2" role="option" tabindex="-1">horse</div>`\
`</div>`
Note the `listbox` role and that each child of the `listbox` has a role of `option`. This is the only way that a `listbox` will provide the correct information to screen readers.
Also note that the `listbox` has a property called `aria-activedescendant`. This keeps track of the “active” option as the user searches through the options with the up and down keys. It uses the current option’s `id` as its value, and that value is updated with JavaScript. That way, whenever a new option is made active, screen readers should announce the option’s text, such as “cat,” and the index of the option, such as “two of three.”
To choose the selected list option, the user can hit enter, which clears the list of options from the `listbox` and refocuses the input field:
`if (e.keyCode == 13) {`\
`e.preventDefault();`\
`e.stopPropagation();`\
`$('#pets').focus();`\
`}`
## Code editor
See [this custom autocomplete implementation in a code editor](https://codepen.io/team/hwpdas/pen/Yzyrjrb). Try operating it with just your keyboard, with a screen reader running at the same time.
See also:
- [Techniques](https://accessibility.huit.harvard.edu/page-categories/techniques)
- [Controls](https://accessibility.huit.harvard.edu/accessibility-topics/controls)
- [Inputs](https://accessibility.huit.harvard.edu/accessibility-topics/inputs)
- [Screen reader](https://accessibility.huit.harvard.edu/access-technologies/screen-reader)
- [Keyboard](https://accessibility.huit.harvard.edu/access-technologies/keyboard)
- [Speech recognition](https://accessibility.huit.harvard.edu/access-technologies/speech-recognition)
- [Switch-based input](https://accessibility.huit.harvard.edu/access-technologies/switch-based-output)
- [Custom widgets and controls ✎](https://accessibility.huit.harvard.edu/content/custom-widgets-and-controls)
- [Provide name, role, and value information ✎](https://accessibility.huit.harvard.edu/content/provide-name-role-and-value-information)
- [Use accessible design patterns ✎](https://accessibility.huit.harvard.edu/content/use-accessible-design-patterns)
- [Operable](https://accessibility.huit.harvard.edu/techniques/principles/operable)
- [Robust](https://accessibility.huit.harvard.edu/principles/robust)
- [Blind](https://accessibility.huit.harvard.edu/disabilities/blind)
- [Motor impairment](https://accessibility.huit.harvard.edu/disabilities/motor-impairment)
- [HTML](https://accessibility.huit.harvard.edu/web-technologies/html)
- [JavaScript](https://accessibility.huit.harvard.edu/web-technologies/javascript)