Skip to content

Commit

Permalink
Add default value to autocomplete input
Browse files Browse the repository at this point in the history
Adding the accessible autocomplete element meant that when completing a text search from the home page (non-js route) the input value is no longer populated when the search page is loaded. We have added a default value on init autocomplete.

There is a known issue with autocomplete (alphagov/accessible-autocomplete#424), that setting a default value results in a suggestion with the text 'undefined'. This is bedause the default value is treated as a selected item, even though it is likely to be a partial search term, and is a string instead of an Aucomplete empty object. The workaround for this is to check if the result is a string when setting the custom template.
  • Loading branch information
lookupdaily committed Sep 8, 2023
1 parent 8db68a9 commit abba43b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@

<script asp-add-nonce type="application/javascript">
window.onload = () => {
Autocomplete.loadTrustSearch("@Model.InputId")
Autocomplete.loadTrustSearch("@Model.InputId", "@Model.KeyWords")
}
</script>
Original file line number Diff line number Diff line change
@@ -1,37 +1,51 @@
import accessibleAutocomplete from 'accessible-autocomplete'

export class Autocomplete {
loadTrustSearch = async (inputId) => {
suggest = async (query, populateResults) => {
let loading = false
if (query && !loading) {
loading = true
const response = await fetch(`/search?handler=populateautocomplete&keywords=${query}`)
const results = await response.json()
populateResults(results)
loading = false
}
}

getName = (result) => {
// This check for a string is related to a known issue in autocomplete when setting a default value https://github.com/alphagov/accessible-autocomplete/issues/424
if (result && typeof (result) !== 'string') return result && result.name
return result
}

getHint = (result) => {
const hintText = this.getName(result)
if (result?.address) {
return `${hintText}<span class="autocomplete__option-hint">${result.address}</span>`
}
return hintText
}

loadTrustSearch = async (inputId, defaultValue) => {
const autocompleteTemplate = document.getElementById(`${inputId}-js-autocomplete-template`)
const autocompleteTemplateContents = autocompleteTemplate.content.cloneNode(true)
const elementToReplace = document.getElementById(`${inputId}-no-js-search-container`)

elementToReplace.replaceWith(autocompleteTemplateContents)

async function suggest (query, populateResults) {
if (query && !loading) {
loading = true
const response = await fetch(`/search?handler=populateautocomplete&keywords=${query}`)
const results = await response.json()
populateResults(results)
loading = false
}
}

accessibleAutocomplete({
defaultValue,
element: document.getElementById(`${inputId}-autocomplete-container`),
id: inputId,
name: 'keywords',
source: suggest,
source: this.suggest,
autoselect: false,
confirmOnBlur: false,
showNoOptionsFound: false,
displayMenu: 'overlay',
minLength: 3,
templates: {
inputValue: function (r) { return r && r.name },
suggestion: function (r) { return r && `${r.name}<span class="autocomplete__option-hint">${r.address}</span>` }
inputValue: this.getName,
suggestion: this.getHint
},
onConfirm: (selected) => {
if (selected) {
Expand Down

0 comments on commit abba43b

Please sign in to comment.