Skip to content

Commit

Permalink
feat: extended clear search scripts to allow multiple forms/inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
jgorfine-zendesk authored and luis-almeida committed Mar 14, 2022
1 parent be0a379 commit a3c0e94
Showing 1 changed file with 32 additions and 25 deletions.
57 changes: 32 additions & 25 deletions script.js
Expand Up @@ -11,14 +11,23 @@ function debounce(callback, wait) {
}

// Define variables for search field
let searchForm, searchInput, searchClearButton;
let searchFormFilledClassName = "search-has-value";
let searchFormSelector = "form[role='search']";

// Clear the search input, and then return focus to it
function clearSearchInput() {
searchForm.classList.remove(searchFormFilledClassName);
searchInput.value = "";
searchInput.focus();
function clearSearchInput(event) {
event.target.closest(searchFormSelector).classList.remove(searchFormFilledClassName);

let input;
if (event.target.tagName === "INPUT") {
input = event.target;
} else if (event.target.tagName === "BUTTON") {
input = event.target.previousElementSibling;
} else {
input = event.target.closest("button").previousElementSibling;
}
input.value = "";
input.focus();
}

// Have the search input and clear button respond
Expand All @@ -27,7 +36,7 @@ function clearSearchInput() {
function clearSearchInputOnKeypress(event) {
const searchInputDeleteKeys = ["Delete", "Escape"];
if (searchInputDeleteKeys.includes(event.key)) {
clearSearchInput();
clearSearchInput(event);
}
}

Expand All @@ -43,10 +52,10 @@ function getClearSearchButtonLabel() {
// To learn more about this, see:
// https://adrianroselli.com/2019/07/ignore-typesearch.html#Delete
// https://www.scottohara.me/blog/2022/02/19/custom-clear-buttons.html
function buildClearSearchButton() {
function buildClearSearchButton(inputId) {
const button = document.createElement("button");
button.setAttribute("type", "button");
button.setAttribute("aria-controls", searchInput.id);
button.setAttribute("aria-controls", inputId);
button.classList.add("clear-button");
const buttonLabel = getClearSearchButtonLabel();
const icon = `<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' focusable='false' role='img' viewBox='0 0 12 12' aria-label='${buttonLabel}'><path stroke='currentColor' stroke-linecap='round' stroke-width='2' d='M3 9l6-6m0 6L3 3'/></svg>`;
Expand All @@ -57,27 +66,22 @@ function buildClearSearchButton() {
}

// Append the clear button to the search form
function appendClearSearchButton() {
searchClearButton = buildClearSearchButton();
searchForm.append(searchClearButton);
if (searchInput.value.length > 0) {
searchForm.classList.add(searchFormFilledClassName);
function appendClearSearchButton(input, form) {
searchClearButton = buildClearSearchButton(input.id);
form.append(searchClearButton);
if (input.value.length > 0) {
form.classList.add(searchFormFilledClassName);
}
}

// Add a class to the search form when the input has a value;
// Remove that class from the search form when the input doesn't have a value.
// Do this on a delay, rather than on every keystroke.
const toggleClearSearchButtonAvailability = debounce(function() {
searchForm.classList.toggle(searchFormFilledClassName, searchInput.value.length > 0);
const toggleClearSearchButtonAvailability = debounce(function(event) {
const form = event.target.closest(searchFormSelector);
form.classList.toggle(searchFormFilledClassName, event.target.value.length > 0);
}, 200)

// Ensure the search field responds appropriately to typing + keyboard interactions
function handleSearchInputKeyup(event) {
clearSearchInputOnKeypress(event);
toggleClearSearchButtonAvailability();
}

document.addEventListener('DOMContentLoaded', function() {
// Key map
var ENTER = 13;
Expand All @@ -103,10 +107,13 @@ document.addEventListener('DOMContentLoaded', function() {
}

// Set up clear functionality for the search field
searchForm = document.querySelector("form[role='search']");
searchInput = searchForm.querySelector("input[type='search']");
searchInput.addEventListener("keyup", handleSearchInputKeyup);
appendClearSearchButton();
const searchForms = [...document.querySelectorAll(searchFormSelector)];
const searchInputs = searchForms.map(form => form.querySelector("input[type='search']"));
searchInputs.forEach((input) => {
appendClearSearchButton(input, input.closest(searchFormSelector));
input.addEventListener("keyup", clearSearchInputOnKeypress);
input.addEventListener("keyup", toggleClearSearchButtonAvailability);
});

// social share popups
Array.prototype.forEach.call(document.querySelectorAll('.share a'), function(anchor) {
Expand Down

0 comments on commit a3c0e94

Please sign in to comment.