Custom clear button logic

This commit is contained in:
zandercymatics 2024-08-09 11:44:59 -06:00
parent 730677b85e
commit 5b541b8c03
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7

View file

@ -1992,6 +1992,9 @@ document.addEventListener('DOMContentLoaded', function() {
* We want the search bar to act soley as a search bar. * We want the search bar to act soley as a search bar.
*/ */
(function loadInitialValuesForComboBoxes() { (function loadInitialValuesForComboBoxes() {
var overrideDefaultClearButton = true;
var isTyping = false;
document.addEventListener('DOMContentLoaded', (event) => { document.addEventListener('DOMContentLoaded', (event) => {
// The file location for the #undo svg // The file location for the #undo svg
const undoIcon = document.querySelector("#uswds-undo-icon-url"); const undoIcon = document.querySelector("#uswds-undo-icon-url");
@ -2005,10 +2008,13 @@ document.addEventListener('DOMContentLoaded', function() {
const comboBoxElements = document.querySelectorAll(".usa-combo-box"); const comboBoxElements = document.querySelectorAll(".usa-combo-box");
comboBoxElements.forEach(comboBox => { comboBoxElements.forEach(comboBox => {
const input = comboBox.querySelector('input'); const input = comboBox.querySelector('input');
if (!input || !undoIconUrl) { const select = comboBox.querySelector("select");
console.warn("No input element found"); if (!input || !undoIconUrl || !select) {
console.warn("No combobox element found");
return; return;
} }
// Set the initial value of the combobox
let initialValue = select.getAttribute("data-default-value");
let clearInputButton = comboBox.querySelector(".usa-combo-box__clear-input"); let clearInputButton = comboBox.querySelector(".usa-combo-box__clear-input");
if (!clearInputButton) { if (!clearInputButton) {
@ -2016,34 +2022,76 @@ document.addEventListener('DOMContentLoaded', function() {
return; return;
} }
let resetSearchButton = clearInputButton.cloneNode(true); // Override the default clear button behavior such that it no longer clears the input,
resetSearchButton.classList.add('usa-combo-box__reset-search'); // it just resets to the data-initial-value.
resetSearchButton.style.display = 'none';
// Change the icon to the "undo" icon. Due to the nature of how this element is styled, we have to do this as so.
resetSearchButton.style.backgroundImage = `url("${undoIconUrl}"), linear-gradient(transparent, transparent)`;
clearInputButton.insertAdjacentElement('afterend', resetSearchButton);
// Show the reset search button when typing // Due to the nature of how uswds works, this is slightly hacky.
// Use a MutationObserver to watch for changes in the dropdown list
const dropdownList = document.querySelector(`#${input.id}--list`);
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === "childList") {
addBlankOption(clearInputButton, dropdownList, initialValue);
}
});
});
// Configure the observer to watch for changes in the dropdown list
const config = { childList: true, subtree: true };
observer.observe(dropdownList, config);
// Add input event listener to detect typing
input.addEventListener('input', () => { input.addEventListener('input', () => {
resetSearchButton.style.display = 'inline-block'; isTyping = true;
}); });
// Hide the reset search button when input loses focus // Add blur event listener to reset typing state
input.addEventListener('blur', () => { input.addEventListener('blur', () => {
resetSearchButton.style.display = 'none'; isTyping = false;
}); });
handleMouseDownOnButton(resetSearchButton, input) // Change the default input behaviour - have it reset to the data default instead
clearInputButton.addEventListener("click", (e) => {
if (overrideDefaultClearButton && initialValue) {
e.preventDefault();
e.stopPropagation();
input.click();
// Find the dropdown option with the desired value
const dropdownOptions = document.querySelectorAll(".usa-combo-box__list-option");
if (dropdownOptions) {
dropdownOptions.forEach(option => {
if (option.getAttribute("data-value") === initialValue) {
// Simulate a click event on the dropdown option
option.click();
}
});
}
}
});
}); });
} }
function handleMouseDownOnButton(button, inputToTarget) { function addBlankOption(clearInputButton, dropdownList, initialValue) {
// Reset the input value when the reset search button is clicked if (dropdownList && !dropdownList.querySelector('[data-value=""]') && !isTyping) {
button.addEventListener('mousedown', (event) => { const blankOption = document.createElement("li");
// Simulate focus and blur to trigger the built in "resetSelection" and "hideList" functions blankOption.setAttribute("role", "option");
inputToTarget.focus(); blankOption.setAttribute("data-value", "");
inputToTarget.blur(); blankOption.classList.add("usa-combo-box__list-option");
button.style.display = 'none'; if (!initialValue){
}); blankOption.classList.add("usa-combo-box__list-option--selected")
}
blankOption.textContent = "---------";
dropdownList.insertBefore(blankOption, dropdownList.firstChild);
blankOption.addEventListener("click", (e) => {
e.preventDefault();
e.stopPropagation();
overrideDefaultClearButton = false;
// Trigger the default clear behavior
clearInputButton.click();
overrideDefaultClearButton = true;
});
}
} }
})(); })();