Skip to content

Commit

Permalink
Add autocomplete stimulus controller
Browse files Browse the repository at this point in the history
This is based on the implementation in the prototype and customises the
accessible-autocomplete with some of the available options.
  • Loading branch information
tvararu committed Sep 27, 2024
1 parent 84f4e52 commit 1f4488e
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 15 deletions.
44 changes: 44 additions & 0 deletions app/assets/stylesheets/_autocomplete.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Ensure the autocomplete uses the correct typeface
.autocomplete__wrapper {
font-family: $govuk-font-family;
}

.autocomplete__input {
font-family: inherit;
}

// Style the autocomplete if there’s an error
.nhsuk-form-group--error {
.autocomplete__input {
border-color: $govuk-error-colour;
}

.autocomplete__input--focused {
border-color: $govuk-input-border-colour;
}
}

.autocomplete__dropdown-arrow-down {
// Ensure dropdown arrow can be clicked
// https://github.com/alphagov/accessible-autocomplete/issues/202
pointer-events: none;
// Ensure dropdown arrow can be seen
z-index: 0;
}

.autocomplete__input {
background-color: $color_nhsuk-white;
}

.autocomplete__option {
margin-bottom: 0;
}

.autocomplete__option-hint {
color: $nhsuk-secondary-text-color;

.autocomplete__option:hover &,
.autocomplete__option:focus & {
color: $color_nhsuk-grey-5;
}
}
1 change: 1 addition & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ $color_app-dark-orange: darken(

// Application components
@import "action_list";
@import "autocomplete";
@import "button";
@import "button-group";
@import "card";
Expand Down
60 changes: 60 additions & 0 deletions app/javascript/controllers/autocomplete_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Controller } from "@hotwired/stimulus";
import accessibleAutocomplete from "accessible-autocomplete";

const enhanceOption = (option) => {
return {
name: option.label,
append: option.getAttribute("data-append"),
hint: option.getAttribute("data-hint"),
};
};

const suggestion = (value, options) => {
const option = options.find(({ name }) => name === value);
if (option) {
const html = option.append ? `${value}${option.append}` : value;
return option.hint
? `${html}<br><span class="autocomplete__option-hint">${option.hint}</span>`
: html;
} else {
return "No results found";
}
};

const autocomplete = ($module) => {
if (!$module) {
return;
}

const params = $module.dataset;

const selectOptions = Array.from($module.options);
const options = selectOptions.map((option) => enhanceOption(option));

accessibleAutocomplete.enhanceSelectElement({
autoselect: params.autoselect === "true",
defaultValue: params.defaultValue || "",
displayMenu: params.displayMenu,
minLength: params.minLength ? parseInt(params.minLength) : 0,
selectElement: $module,
showAllValues: params.showAllValues === "true",
showNoOptionsFound: params.showNoOptionsFound === "true",
templates: {
suggestion: (value) => suggestion(value, options),
},
onConfirm: (value) => {
const selectedOption = [].filter.call(
selectOptions,
(option) => (option.textContent || option.innerText) === value,
)[0];
if (selectedOption) selectedOption.selected = true;
},
});
};

// Connects to data-module="autocomplete"
export default class extends Controller {
connect() {
autocomplete(this.element);
}
}
3 changes: 3 additions & 0 deletions app/javascript/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

import { application } from "./application";

import AutocompleteController from "./autocomplete_controller";
application.register("autocomplete", AutocompleteController);

import AutosubmitController from "./autosubmit_controller";
application.register("autosubmit", AutosubmitController);

Expand Down
1 change: 1 addition & 0 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<title><%= page_title(@service_name) %></title>

<%= stylesheet_link_tag "accessible-autocomplete/dist/accessible-autocomplete.min", "data-turbo-track": Rails.env.development? ? "" : "reload" %>
<%= stylesheet_link_tag "application", "data-turbo-track": Rails.env.development? ? "" : "reload" %>
<%= javascript_include_tag "application", "data-turbo-track": Rails.env.development? ? "" : "reload", defer: true %>
Expand Down
22 changes: 7 additions & 15 deletions app/views/parent_interface/consent_forms/edit/school.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,13 @@
If you&apos;ve moved recently, it&apos;s important to mention this.
</p>

<%= render DfE::Autocomplete::View.new(
f,
attribute_name: :location_id,
form_field: f.govuk_select(
:location_id,
options_for_select(
dfe_autocomplete_options(
@consent_form.eligible_schools.map {
OpenStruct.new(name: _1.name, value: _1.id)
}
),
f.object.id,
),
label: { text: "Select a school" },
),
<%= f.govuk_collection_select(
:location_id,
@consent_form.eligible_schools,
:id,
:name,
label: { text: "Select a school" },
data: { module: "autocomplete" },
) %>
<%= f.govuk_submit "Continue" %>
Expand Down
4 changes: 4 additions & 0 deletions config/initializers/assets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
Rails.application.config.assets.paths << Rails.root.join("node_modules")
Rails.application.config.assets.precompile += %w[
accessible-autocomplete/dist/accessible-autocomplete.min.css
]
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"dependencies": {
"@hotwired/stimulus": "^3.2.2",
"@hotwired/turbo-rails": "^8.0.10",
"accessible-autocomplete": "^3.0.1",
"esbuild": "^0.24.0",
"govuk-frontend": "^5.6.0",
"idb": "^8.0.0",
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1895,6 +1895,11 @@ abab@^2.0.6:
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291"
integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==

accessible-autocomplete@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/accessible-autocomplete/-/accessible-autocomplete-3.0.1.tgz#8ddf4934d0b4ba6acb28de486dd505e062cdc86e"
integrity sha512-xMshgc2LT5addvvfCTGzIkRrvhbOFeylFSnSMfS/PdjvvvElZkakCwxO3/yJYBWyi1hi3tZloqOJQ5kqqJtH4g==

acorn-globals@^7.0.0:
version "7.0.1"
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3"
Expand Down

0 comments on commit 1f4488e

Please sign in to comment.