diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 3fe3b1813..0e9b04758 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -32,6 +32,13 @@ class UsersController < ApplicationController end end + def search + users = User.search_by_name(params["query"]).limit(20) + x = {} + users.each { |user| x[user.id] = { value: user.name, hint: user.email } } + render json: x.to_json + end + def resend_invite @user.send_confirmation_instructions flash[:notice] = "Invitation sent to #{@user.email}" diff --git a/app/frontend/controllers/index.js b/app/frontend/controllers/index.js index ece539d15..ef29b99ca 100644 --- a/app/frontend/controllers/index.js +++ b/app/frontend/controllers/index.js @@ -13,6 +13,8 @@ import GovukfrontendController from './govukfrontend_controller.js' import NumericQuestionController from './numeric_question_controller.js' +import SearchController from './search_controller.js' + import FilterLayoutController from './filter_layout_controller.js' application.register('accessible-autocomplete', AccessibleAutocompleteController) application.register('conditional-filter', ConditionalFilterController) @@ -20,3 +22,4 @@ application.register('conditional-question', ConditionalQuestionController) application.register('govukfrontend', GovukfrontendController) application.register('numeric-question', NumericQuestionController) application.register('filter-layout', FilterLayoutController) +application.register('search', SearchController) diff --git a/app/frontend/controllers/search_controller.js b/app/frontend/controllers/search_controller.js new file mode 100644 index 000000000..621582c4e --- /dev/null +++ b/app/frontend/controllers/search_controller.js @@ -0,0 +1,47 @@ +import { Controller } from '@hotwired/stimulus' +import accessibleAutocomplete from 'accessible-autocomplete' +import 'accessible-autocomplete/dist/accessible-autocomplete.min.css' +import { searchSuggestion, fetchAndPopulateSearchResults } from '../modules/search' + +let hints = []; +const populateHint = (results) => { + console.log("populating") + hints = results +} + +export default class extends Controller { + connect () { + const selectEl = this.element + const selectOptions = Array.from(selectEl.options).filter(function (option, index, arr) { return option.value !== '' }) + + const matches = /^(\w+)\[(\w+)\]$/.exec(selectEl.name) + const rawFieldName = matches ? `${matches[1]}[${matches[2]}_raw]` : '' + + accessibleAutocomplete.enhanceSelectElement({ + defaultValue: '', + selectElement: selectEl, + minLength: 1, + source: (query, populateResults) => { + fetchAndPopulateSearchResults(query, populateResults, populateHint) + }, + autoselect: true, + placeholder: 'Start typing to search', + templates: { suggestion: (value) => searchSuggestion(value, hints) }, + name: rawFieldName, + onConfirm: (val) => { + const selectedOption = [].filter.call( + selectOptions, + (option) => (getSearchableName(option)) === val + )[0] + if (selectedOption) selectedOption.selected = true + } + }) + + const parentElement = selectEl.parentElement + const inputElement = parentElement.querySelector('[role=combobox]') + + inputElement.addEventListener('input', () => { + selectOptions.forEach((option) => { option.selected = false }) + }) + } +} diff --git a/app/frontend/modules/search.js b/app/frontend/modules/search.js index 71944746e..6913f0372 100644 --- a/app/frontend/modules/search.js +++ b/app/frontend/modules/search.js @@ -117,6 +117,21 @@ export const suggestion = (value, options) => { } } +export const searchSuggestion = (value, hints) => { + try { + const result = hints[value.toString()] + if (result) { + const html = result.append ? `${result.value} ${result.append}` : `${result.value}` + return result.hint ? `${html}