Skip to content

Instantly share code, notes, and snippets.

@alextea
Last active December 7, 2022 17:03
Show Gist options
  • Save alextea/2ec78934472fdb3b1433b342c2ef18d3 to your computer and use it in GitHub Desktop.
Save alextea/2ec78934472fdb3b1433b342c2ef18d3 to your computer and use it in GitHub Desktop.
This is a step by step guide on how to use the accessible autocomplete component in the GOV.UK prototype kit

Using accessible autocomplete in the GOV.UK prototype kit

This is a step by step guide on how to use the accessible autocomplete component in the GOV.UK prototype kit. There aren’t any instructions included with the code for using with the prototype kit, and it’s not straightforward if you’re not familiar with javascript.

I have an example repo you can download to check the code.

Download

Download the accessible autocomplete code, you can download the zip or clone the repo if you prefer to use git.

Copy the files to your prototype

Copy the minified files from the /dist folder to your prototype.

Copy accessible-autocomplete.min.js to app/assets/javascripts (you can also copy accessible-autocomplete.min.js.map if you want to keep the source map for debugging.

Copy accessible-autocomplete.min.css to app/assets/css (you will need to create this folder).

Include the javascript and CSS

Include the javascript file in app/views/layouts/main.html

Add the following code to the end of the file:

{% block scripts %}
  {{ super() }}
  <script src="/public/javascripts/accessible-autocomplete.min.js"></script>
{% endblock %}

Include the CSS file in app/views/layouts/main.html

Add the following code to the end of the file:

{% block stylesheets %}
  {{ super() }}
  <link href="/public/css/accessible-autocomplete.min.css" rel="stylesheet" type="text/css" />
{% endblock %}

You will also need to add some styles to fix the font for the autocomplete input and results. Add this to the end of app/assets/sass/application.scss:

.autocomplete__wrapper * {
  @include govuk-typography-common();
}

Set up your select tag

Enhancing a select tag is probably the easiest way to get the autocomplete set up in the prototype kit. You can put the data right in the view, rather than importing it using client side javascript. Using progressive enhancement also means it’s available to users when javascript is unavailable.

In our example we have a select tag showing a list of countries and territories. It has 278 options – obviously too many for a dropdown to be easy to use.

<select class="govuk-select" name="choose-country" id="choose-country">
  <option value="territory:AE-AZ">Abu Dhabi</option>
  <option value="country:AF">Afghanistan</option>
  <option value="territory:AE-AJ">Ajman</option>
  <option value="territory:XQZ">Akrotiri</option>
  <option value="country:AL">Albania</option>
  ...
  <option value="country:ZM">Zambia</option>
  <option value="country:ZW">Zimbabwe</option>
  <option value="territory:AX">Åland Islands</option>
</select>

To turn the select into an autocomplete we need to add the following javascript to app/assets/javascripts/application.js inside the window.GOVUKPrototypeKit.documentReady(() => { ... } block:

let selectElement = document.querySelector('#choose-country')

accessibleAutocomplete.enhanceSelectElement({
  defaultValue: '',
  selectElement: selectElement
})

You should change the id inside the querySelector function to match the id of your select tag.

You should now be able to search the options using the autocomplete.

Set up synonym searching

Often when using autocomplete you want to allow users to search for a result using a synonym.

In the following example we’ll add some javascript to use the values from the select’s option tags as synonyms.

Add the source option to the autocomplete code in app/assets/javascripts/application.js:

let selectElement = document.querySelector('#choose-country')

accessibleAutocomplete.enhanceSelectElement({
  defaultValue: '',
  source: (query, populateResults) => {
    const options = selectElement.querySelectorAll('option')
    let results = []

    options.forEach(
      (opt, i, list) => {
        let queryRegExp = new RegExp(query.trim(), 'i')
        let value = opt.getAttribute('value')
        let text = opt.innerText.trim()
        if (queryRegExp.test(value) || queryRegExp.test(text)) {
          results.push(text)
        }
      }
    )

    populateResults(results)
  },
  selectElement: selectElement
})

You should now be able to search using the country codes. Try typing “gb” or “az” and see which results appear.

Next steps

You could further adapt this code to use a data attribute attached to the options, and could populate this with multiple synonyms, separated by a delimiter.

@Kirill-Titov-Designer
Copy link

Thanks! It's great, works as a charm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment