Autocomplete
About
What does it do?
The autocomplete component is an input field that offers the user text suggestions as they type. This is often done by hitting an API endpoint with the users query when the user has finished typing.
The autocomplete pattern is a combination of the input and loader components.
When to use it?
- As a progressive enhancement to make a users journey shorter/easier when searching
- When you have a smaller data set/list that is quick to query
- When you want to ensure the user submits a relevant query/value
When not to use it?
- When you have a massive set of data, instead you should have an input/search that shows results after submission.
- Don't use this component as if it is a search box. Autocomplete is to suggest a value to a user via it's results not act as a results page for a search.
Default state
In its default state, the autcomplete component is made up of a text input with a search icon.
For best practice, ensure that the placeholder and aria-label describes what the autocompletes intended purpose is.
Notice that there is also a wmnds-loader
component nested within the autocomplete, more on that in the next section.
Content is loading...
HTML markup
<label class="wmnds-fe-label" for="autoComplete">Autocomplete label</label>
<div class="wmnds-autocomplete wmnds-grid">
<!-- Search icon -->
<svg class="wmnds-autocomplete__icon">
<use xlink:href="#wmnds-general-search" href="#wmnds-general-search"></use>
</svg>
<!-- normal sized loader -->
<div class="wmnds-loader" role="alert" aria-live="assertive">
<p class="wmnds-loader__content">Content is loading...</p>
</div>
<!-- Autocomplete input box -->
<input class="wmnds-fe-input wmnds-autocomplete__input wmnds-col-1" value="" placeholder="Tap to search" name="autoComplete" aria-label="Tap to search" type="text" id="autoComplete" required="false" autocomplete="off">
</div>
Nunjucks markup
{% from "wmnds/patterns/autocomplete/_autocomplete.njk" import wmndsAutocomplete %}
{{
compExample([
wmndsAutocomplete({
id: 'selectedState',
selected: false,
selectedItem: '',
})
])
}}
Nunjucks properties
Name | Type | Description |
---|---|---|
id | string | Required. String of text used for the search in the autocomplete. |
query | string | String of text used for the search in the autocomplete. |
placeholder | string | Text used for the placeholder in the autocomplete input. |
loading | boolean | If true, loading spinner will be visible in the autocomplete. |
isRequired | boolean | Indictes whether an autocomplete response is required |
selected | boolean | If true, the autocomplete will display in the selected state |
selectedItem | string | Text to show in the selected state if selected is true |
Loading
When a user types in a query, you may want to have some code that hits an API or gets the data/suggestions for the autocomplete from somewhere. To help users understand that they need to wait for something we can change the autocomplete to a loading state. We do this by adding the class wmnds--is-loading
to the top level of the autocomplete (this is the only difference between the loading state and default state code snippets).
As mentioned in the previous section, there is a wmnds-loader
component nested in the autocomplete.
When adding the wmnds--is-loading
class, it will hide the search icon and show the loading spinner in it's place.
Below is an example of how the autocomplete looks when a user has typed in 'My query' and is waiting for autocomplete suggestions to load.
It is good practice to:
- Show loading state when waiting for data to load
- Let the user finish typing before you fetch autocomplete suggestions (add a debounce)
- Add the wmnds-is--loading class as soon as you are fetching data
Content is loading...
HTML markup
<label class="wmnds-fe-label" for="autoCompleteQuery">Autocomplete label</label>
<div class="wmnds-autocomplete wmnds-grid wmnds-is--loading">
<!-- Search icon -->
<svg class="wmnds-autocomplete__icon">
<use xlink:href="#wmnds-general-search" href="#wmnds-general-search"></use>
</svg>
<!-- normal sized loader -->
<div class="wmnds-loader" role="alert" aria-live="assertive">
<p class="wmnds-loader__content">Content is loading...</p>
</div>
<!-- Autocomplete input box -->
<input class="wmnds-fe-input wmnds-autocomplete__input wmnds-col-1" value="My query" placeholder="Tap to search" name="autoCompleteQuery" aria-label="Tap to search" type="text" id="autoCompleteQuery" required="false" autocomplete="off">
</div>
Nunjucks markup
{% from "wmnds/patterns/autocomplete/_autocomplete.njk" import wmndsAutocomplete %}
{{
compExample([
wmndsAutocomplete({
id: 'selectedState',
selected: false,
selectedItem: '',
})
])
}}
Nunjucks properties
Name | Type | Description |
---|---|---|
id | string | Required. String of text used for the search in the autocomplete. |
query | string | String of text used for the search in the autocomplete. |
placeholder | string | Text used for the placeholder in the autocomplete input. |
loading | boolean | If true, loading spinner will be visible in the autocomplete. |
isRequired | boolean | Indictes whether an autocomplete response is required |
selected | boolean | If true, the autocomplete will display in the selected state |
selectedItem | string | Text to show in the selected state if selected is true |
Suggestions
It's good practice to:
- Show the suggestions in an unordered list
- Ensure there is a title tag on the
.wmnds-autocomplete-suggestions__li
describing further information about the suggestion - Ensure there is a
tabindex="0"
attribute on the.wmnds-autocomplete-suggestions__li
to allow users to tab through the results with a keyboard
Default (text)
The most commonly used suggestions will be displayed as text only.
It is good practice to:
- Bold characters that match the users query
Content is loading...
- This is my query result 1
- This is my query result 2
- This is my query result 3
HTML markup
<label class="wmnds-fe-label" for="autoCompleteSuggestions">Autocomplete label</label>
<div class="wmnds-autocomplete wmnds-grid">
<!-- Search icon -->
<svg class="wmnds-autocomplete__icon">
<use xlink:href="#wmnds-general-search" href="#wmnds-general-search"></use>
</svg>
<!-- normal sized loader -->
<div class="wmnds-loader" role="alert" aria-live="assertive">
<p class="wmnds-loader__content">Content is loading...</p>
</div>
<!-- Autocomplete input box -->
<input class="wmnds-fe-input wmnds-autocomplete__input wmnds-col-1" value="My query" placeholder="Tap to search" name="autoCompleteSuggestions" aria-label="Tap to search" type="text" id="autoCompleteSuggestions" required="false" autocomplete="off">
</div>
<!-- Autocomplete suggestions -->
<ul class="wmnds-autocomplete-suggestions">
<li class="wmnds-autocomplete-suggestions__li" title="Search result 1" tabindex="0">
This is <strong>my query</strong> result 1
</li>
<li class="wmnds-autocomplete-suggestions__li" title="Search result 2" tabindex="0">
This is <strong>my query</strong> result 2
</li>
<li class="wmnds-autocomplete-suggestions__li" title="Search result 3" tabindex="0">
This is <strong>my query</strong> result 3
</li>
</ul>
Nunjucks markup
{% from "wmnds/patterns/autocomplete/_autocomplete.njk" import wmndsAutocomplete %}
{{
compExample([
wmndsAutocomplete({
id: 'selectedState',
selected: false,
selectedItem: '',
})
])
}}
Nunjucks properties
Name | Type | Description |
---|---|---|
id | string | Required. String of text used for the search in the autocomplete. |
query | string | String of text used for the search in the autocomplete. |
placeholder | string | Text used for the placeholder in the autocomplete input. |
loading | boolean | If true, loading spinner will be visible in the autocomplete. |
isRequired | boolean | Indictes whether an autocomplete response is required |
selected | boolean | If true, the autocomplete will display in the selected state |
selectedItem | string | Text to show in the selected state if selected is true |
With disruption indicator
This autocomplete is combined with the medium / normal - disruption indicator component.
You will notice that the suggestions are much bigger than text only results, and have an overflow scrollbar. This scrollbar will appear if the height of the suggestion container goes over a certain height.
As you can see from the code snippet, the main wmnds-autocomplete-suggestions
and wmnds-autocomplete-suggestions__li
classes are prevelant on the ul and li elements. Within the li element we have nested the disruption indicator component whilst also using the WMNDS grid. This gives enough flexibility to style the suggestions to how we want, find out more in the next section.
Content is loading...
- X15Oldbury to Dudley 1
and return journey - X15Oldbury to Dudley 2
and return journey - X15Oldbury to Dudley 3
and return journey - X15Oldbury to Dudley 4
and return journey - X15Oldbury to Dudley 5
and return journey
HTML markup
<label class="wmnds-fe-label" for="genericInput">Autocomplete label</label>
<div class="wmnds-autocomplete wmnds-grid">
<!-- Search icon -->
<svg class="wmnds-autocomplete__icon">
<use xlink:href="#wmnds-general-search" href="#wmnds-general-search"></use>
</svg>
<!-- normal sized loader -->
<div class="wmnds-loader" role="alert" aria-live="assertive">
<p class="wmnds-loader__content">Content is loading...</p>
</div>
<!-- Autocomplete input box -->
<input class="wmnds-fe-input wmnds-autocomplete__input wmnds-col-1" value="x15" placeholder="Tap to search" name="genericInput" aria-label="Tap to search" type="text" id="genericInput" required="false" autocomplete="off">
</div>
<!-- Autocomplete suggestions -->
<ul class="wmnds-autocomplete-suggestions">
<li class="wmnds-autocomplete-suggestions__li wmnds-grid" title="Good service on X15" tabindex="0">
<div class="wmnds-col-auto">
<div class="wmnds-disruption-indicator-medium">
<span class="wmnds-disruption-indicator-medium__service">X15</span>
</div>
</div>
<div class="wmnds-col-1-2 wmnds-col-sm-2-3">
<strong>Oldbury to Dudley 1</strong><br>and return journey
</div>
</li>
<li class="wmnds-autocomplete-suggestions__li wmnds-grid" title="Good service on X15" tabindex="0">
<div class="wmnds-col-auto">
<div class="wmnds-disruption-indicator-medium">
<span class="wmnds-disruption-indicator-medium__service">X15</span>
</div>
</div>
<div class="wmnds-col-1-2 wmnds-col-sm-2-3">
<strong>Oldbury to Dudley 2</strong><br>and return journey
</div>
</li>
<li class="wmnds-autocomplete-suggestions__li wmnds-grid" title="Good service on X15" tabindex="0">
<div class="wmnds-col-auto">
<div class="wmnds-disruption-indicator-medium">
<span class="wmnds-disruption-indicator-medium__service">X15</span>
</div>
</div>
<div class="wmnds-col-1-2 wmnds-col-sm-2-3">
<strong>Oldbury to Dudley 3</strong><br>and return journey
</div>
</li>
<li class="wmnds-autocomplete-suggestions__li wmnds-grid" title="Good service on X15" tabindex="0">
<div class="wmnds-col-auto">
<div class="wmnds-disruption-indicator-medium">
<span class="wmnds-disruption-indicator-medium__service">X15</span>
</div>
</div>
<div class="wmnds-col-1-2 wmnds-col-sm-2-3">
<strong>Oldbury to Dudley 4</strong><br>and return journey
</div>
</li>
<li class="wmnds-autocomplete-suggestions__li wmnds-grid" title="Good service on X15" tabindex="0">
<div class="wmnds-col-auto">
<div class="wmnds-disruption-indicator-medium">
<span class="wmnds-disruption-indicator-medium__service">X15</span>
</div>
</div>
<div class="wmnds-col-1-2 wmnds-col-sm-2-3">
<strong>Oldbury to Dudley 5</strong><br>and return journey
</div>
</li>
</ul>
Nunjucks markup
{% from "wmnds/patterns/autocomplete/_autocomplete.njk" import wmndsAutocomplete %}
{{
compExample([
wmndsAutocomplete({
id: 'selectedState',
selected: false,
selectedItem: '',
})
])
}}
Nunjucks properties
Name | Type | Description |
---|---|---|
id | string | Required. String of text used for the search in the autocomplete. |
query | string | String of text used for the search in the autocomplete. |
placeholder | string | Text used for the placeholder in the autocomplete input. |
loading | boolean | If true, loading spinner will be visible in the autocomplete. |
isRequired | boolean | Indictes whether an autocomplete response is required |
selected | boolean | If true, the autocomplete will display in the selected state |
selectedItem | string | Text to show in the selected state if selected is true |
Customising suggestions
There are many ways in which you can show the suggestions, as the autocomplete component has been built in a way that the suggestion results can be custom styled to how you like.
As long as you have the ul element with the class wmnds-autocomplete-suggestions
which contains a direct child li element that has the class wmnds-autocomplete-suggestions__li
then you can fully customise how you want the suggestions to look.
Selected state
The final state of the autocomplete is selecting a suggestion.
This state confirms the users selection from the dropdown list of suggestions.
It's good practice to:
- Show the selected suggestion in bold characters
- Give the user the option to remove their selection
- Keep the disruption indicator in the selected state if this was included in the list of suggestions
HTML markup
<label class="wmnds-fe-label" for="selectedState">Autocomplete label</label>
<div class="wmnds-autocomplete__selected-item wmnds-grid wmnds-grid--justify-between wmnds-m-t-xs wmnds-m-b-md">
<strong class="wmnds-col-auto wmnds-autocomplete__selected-item-summary">Oldbury to Dudley</strong>
<button type="button" class="wmnds-autocomplete__selected-item-close">
<svg class="wmnds-autocomplete__selected-item-close-icon">
<use xlink:href="#wmnds-general-cross" href="#wmnds-general-cross"></use>
</svg>
</button>
</div>
Nunjucks markup
{% from "wmnds/patterns/autocomplete/_autocomplete.njk" import wmndsAutocomplete %}
{{
compExample([
wmndsAutocomplete({
id: 'selectedState',
selected: false,
selectedItem: '',
})
])
}}
Nunjucks properties
Name | Type | Description |
---|---|---|
id | string | Required. String of text used for the search in the autocomplete. |
query | string | String of text used for the search in the autocomplete. |
placeholder | string | Text used for the placeholder in the autocomplete input. |
loading | boolean | If true, loading spinner will be visible in the autocomplete. |
isRequired | boolean | Indictes whether an autocomplete response is required |
selected | boolean | If true, the autocomplete will display in the selected state |
selectedItem | string | Text to show in the selected state if selected is true |