Aria Autocomplete
![gzip size](http://img.badgesize.io/https://unpkg.com/aria-autocomplete/dist/aria-autocomplete.min.js?compression=gzip)
Accessible, extensible, plain JavaScript autocomplete with multi-select.
I've used a lot of autocomplete plugins, but the combination of accessibility, performance, and functionality that I needed wasn't out there. So I've written this from the ground up for that purpose, building on the brilliant accessibility of GOV.UK's accessible-autocomplete - with more functionality, a smaller file size, and (in my testing) better performance.
Try out the examples
Key design goals and features are:
- multiple selection
- extensible source options: Array of Strings, Array of Objects, a Function, or an endpoint String
- progressive enhancement: Automatic source building through specifying a
<select>
as the element, or an element with child checkboxes. - accessibility: Use of ARIA attributes, custom screen reader announcements, and testing with assistive technologies
- compatibility: Broad browser and device support (IE9+)
- starting values: Automatic selection based on starting values, including for checkboxes,
select
options, and for async handling.
Installation / usage
NPM and a module system
First install it
npm install aria-autocomplete
Then import it, and call it on an element (ideally a text <input />
, but not necessarily...) with a source for your autocomplete options.
import AriaAutocomplete from 'aria-autocomplete';
new AriaAutocomplete(document.getElementById('some-element'), {
source: ArrayOrStringOrFunction
});
Plain JavaScript module
You can copy the dist/aria-autocomplete.min.js file into your project and import it into the browser:
<script type="text/javascript" src="js/aria-autocomplete.min.js"></script>
Styling Aria Autocomplete
I would encourage you to style it yourself to match your own site or application's design. An example stylesheet is included in the repository however at dist/aria-autocomplete.min.css which you can copy into your project and import into the browser:
<link rel="stylesheet" src="css/aria-autocomplete.css" />
Performance
I wrote this from the ground up largely because I needed an autocomplete with better performance than others I'd tried. I've optimised the JavaScript where I can, but in some browsers the list rendering will still be a hit to performance. In my testing, modern browsers can render huge lists (1000+ items) just fine (on my laptop, averaging 40ms in Chrome, and under 20ms in Firefox).
As we all know however, Internet Explorer sucks. If you need to support Internet Explorer, I suggest using a sensible combination for the delay
, maxResults
, and possibly minLength
options, to prevent the browser from freezing as your users type, and to reduce the rendering impact. Testing on my laptop, the list rendering in IE11 would take on average: 55ms for 250 items, 300ms for 650 items, and over 600ms for 1000 items.
API Documentation
At its core, the autocomplete requires only an element, and a source
. When the element is an input, its value will be set using the user's selection(s). If a source
option isn't provided however (is falsy, or an empty Array), and the element is either a <select>
, or has child checkboxes, those will be used to build up the source
.
new AriaAutocomplete(document.getElementById('some-input'), {
source: ['Afghanistan', 'Albania', 'Algeria', ...more]
});
const select = document.getElementById('some-select');
new AriaAutocomplete(select);
const div = document.getElementById('some-div-with-child-checkboxes');
new AriaAutocomplete(div);
Options
The full list of options, and their defaults:
{
name: '',
source: '',
sourceMapping: { value: 'value', label: 'label' },
alsoSearchIn: [],
delay: 100,
minLength: 1,
maxResults: 9999,
showAllControl: false,
confirmOnBlur: true,
multiple: false,
autoGrow: false,
maxItems: 9999,
multipleSeparator: ',',
deleteOnBackspace: false,
asyncQueryParam: 'q',
asyncMaxResultsParam: 'limit',
placeholder: '',
noResultsText: 'No results',
cssNameSpace: 'aria-autocomplete',
listClassName: '',
inputClassName: '',
wrapperClassName: '',
srDeleteText: 'delete',
srDeletedText: 'deleted',
srShowAllText: 'Show all',
srSelectedText: 'selected',
srListLabelText: 'Search suggestions',
srAssistiveText: 'When results are available use up and down arrows to review and '
+ 'enter to select. Touch device users, explore by touch or with swipe gestures.',
srResultsText: length =>
`${length} ${length === 1 ? 'result' : 'results'} available.`,
onSearch: query => query,
onAsyncPrep: url => url,
onAsyncSuccess: (query, xhr) => xhr.responseText,
onResponse: optionsToRender => optionsToRender,
onItemRender: itemData => itemData.label,
onConfirm: selection => {},
onDelete: selection => {},
onReady: componentWrapper => {},
onClose: listElement => {},
onOpen: listElement => {}
}
Calling new AriaAutocomplete(element, options);
returns the API object, which can also be accessed on the element via element.ariaAutocomplete
.