Skip to main content

Your privacy settings

We use cookies to help you with journey planning and relevant disruptions, remember your login and show you content you might be interested in. If you’re happy with the use of cookies by West Midlands Combined Authority and our selected partners, click ‘Accept all cookies’. Or click ‘Manage cookies’ to learn more.

Manage Cookies
Beta

This is a new service - your feedback will help us to improve it.

Patterns

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.



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
NameTypeDescription
idstringRequired. String of text used for the search in the autocomplete.
querystringString of text used for the search in the autocomplete.
placeholderstringText used for the placeholder in the autocomplete input.
loadingbooleanIf true, loading spinner will be visible in the autocomplete.
isRequiredbooleanIndictes whether an autocomplete response is required
selectedbooleanIf true, the autocomplete will display in the selected state
selectedItemstringText 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


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
NameTypeDescription
idstringRequired. String of text used for the search in the autocomplete.
querystringString of text used for the search in the autocomplete.
placeholderstringText used for the placeholder in the autocomplete input.
loadingbooleanIf true, loading spinner will be visible in the autocomplete.
isRequiredbooleanIndictes whether an autocomplete response is required
selectedbooleanIf true, the autocomplete will display in the selected state
selectedItemstringText 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

  • 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
NameTypeDescription
idstringRequired. String of text used for the search in the autocomplete.
querystringString of text used for the search in the autocomplete.
placeholderstringText used for the placeholder in the autocomplete input.
loadingbooleanIf true, loading spinner will be visible in the autocomplete.
isRequiredbooleanIndictes whether an autocomplete response is required
selectedbooleanIf true, the autocomplete will display in the selected state
selectedItemstringText 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.


  • X15
    Oldbury to Dudley 1
    and return journey
  • X15
    Oldbury to Dudley 2
    and return journey
  • X15
    Oldbury to Dudley 3
    and return journey
  • X15
    Oldbury to Dudley 4
    and return journey
  • X15
    Oldbury 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
NameTypeDescription
idstringRequired. String of text used for the search in the autocomplete.
querystringString of text used for the search in the autocomplete.
placeholderstringText used for the placeholder in the autocomplete input.
loadingbooleanIf true, loading spinner will be visible in the autocomplete.
isRequiredbooleanIndictes whether an autocomplete response is required
selectedbooleanIf true, the autocomplete will display in the selected state
selectedItemstringText 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

Oldbury to Dudley

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
NameTypeDescription
idstringRequired. String of text used for the search in the autocomplete.
querystringString of text used for the search in the autocomplete.
placeholderstringText used for the placeholder in the autocomplete input.
loadingbooleanIf true, loading spinner will be visible in the autocomplete.
isRequiredbooleanIndictes whether an autocomplete response is required
selectedbooleanIf true, the autocomplete will display in the selected state
selectedItemstringText to show in the selected state if selected is true