Skip to content

Commit

Permalink
Merge pull request #4727 from pulibrary/i4719_advanced_search_keyboar…
Browse files Browse the repository at this point in the history
…d_navigation

Allows you to use arrow keys to open a combobox and navigate within it
  • Loading branch information
sandbergja authored Jan 29, 2025
2 parents 6ddf1e4 + 60cbd28 commit 0d78909
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 7 deletions.
25 changes: 20 additions & 5 deletions app/components/multiselect_combobox_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
<div class="mb-3 advanced-search-facet row dropdown">
<label class="col-sm-4 control-label advanced-facet-label" for="<%= @dom_id %>"><%= @label %></label>
<input id="<%= @dom_id %>" data-bs-toggle="dropdown" autocomplete="off"
class="col-sm-8 combobox-multiselect" role="combobox"
aria-expanded="false" aria-controls="<%= @listbox_id %>">
<span class="fa fa-caret-down" aria-hidden="true" data-bs-toggle="dropdown"></span>
<ul class="dropdown-menu" role="listbox" aria-label="Options" id="<%= @listbox_id %>">
<input
id="<%= @dom_id %>"
data-bs-toggle="dropdown"
autocomplete="off"
class="col-sm-8 combobox-multiselect"
role="combobox"
aria-expanded="false"
aria-controls="<%= @listbox_id %>"
>
<span
class="fa fa-caret-down"
aria-hidden="true"
data-bs-toggle="dropdown"
></span>
<ul
class="dropdown-menu"
role="listbox"
aria-label="Options"
id="<%= @listbox_id %>"
>
<% if @field_name == 'advanced_location_s' %>
<%= content_tag :li,
'All Princeton Holdings',
Expand Down
2 changes: 1 addition & 1 deletion app/components/numismatics_search_form_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<label for="clause_1_query" class="col-sm-4 control-label advanced-facet-label">Keyword</label>
<div class="col-sm-8">
<%= text_field_tag "clause[1][query]", '', # TODO: if there is an existing keyword search, set it as the default
id: 'clause_1_field',
id: 'clause_1_query',
class: 'form-control',
autocorrect: "off",
autocapitalize: "off",
Expand Down
16 changes: 15 additions & 1 deletion app/javascript/orangelight/multiselect_combobox.es6
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,19 @@ export default class MultiselectCombobox {
this.listElement.querySelectorAll('li').forEach((item) => {
this.#addEventListener(item);
});
this.inputElement.addEventListener('input', (event) => {
this.inputElement.addEventListener('keyup', (event) => {
const isUpOrDownEvent = ['ArrowUp', 'ArrowDown'].includes(event.key);
const getToggleButton = event.target;
const instance = bootstrap.Dropdown.getOrCreateInstance(getToggleButton);
if (isUpOrDownEvent) {
event.stopPropagation();
instance.show();
instance._selectMenuItem(event);

return;
}
});
this.inputElement.addEventListener('keyup', (event) => {
this.updateOptionVisibility();
this.#openDropdownIfClosed();
});
Expand All @@ -65,6 +77,8 @@ export default class MultiselectCombobox {
(event) => {
if (event.code == 'Enter') {
this.toggleItem(item);
} else if (event.code == 'ArrowUp' || event.code == 'ArrowDown') {
return;
} else {
// Send all other events to the input, so that
// anything the user types ends up there
Expand Down
14 changes: 14 additions & 0 deletions spec/system/numismatics_form_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,18 @@
expect(page).to have_content('coin (3)')
end
end
it 'can use keyboard navigation', js: true do
visit '/numismatics'
# Get to the "Denomination" dropdown
10.times do
page.send_keys(:tab)
end
page.send_keys(:down)
expect(page).to have_content('shekel')
active_element = page.evaluate_script("document.activeElement")
expect(active_element.text).to eq("1/2 Penny (1)")
page.send_keys(:down)
active_element = page.evaluate_script("document.activeElement")
expect(active_element.text).to eq("follis (1)")
end
end

0 comments on commit 0d78909

Please sign in to comment.