uswds edits to combobox, default values for comboboxes, cleanup of combobox js

This commit is contained in:
David Kennedy 2025-01-14 18:03:24 -05:00
parent e2486c127d
commit ea509f63ef
No known key found for this signature in database
GPG key ID: 6528A5386E66B96B
4 changed files with 21 additions and 52 deletions

View file

@ -29,6 +29,8 @@
* - tooltip dynamic content updated to include nested element (for better sizing control)
* - modal exposed to window to be accessible in other js files
* - fixed bug in createHeaderButton which added newlines to header button tooltips
* - modified combobox to allow for blank values in list
* - modified aria label for X button in combobox to reflect modified behavior of button
*/
if ("document" in window.self) {
@ -1218,9 +1220,11 @@ const enhanceComboBox = _comboBoxEl => {
input.setAttribute(key, value);
}));
comboBoxEl.insertAdjacentElement("beforeend", input);
// DOTGOV - modified the aria-label of the clear input button to Reset selection to reflect changed button behavior
// <button type="button" class="${CLEAR_INPUT_BUTTON_CLASS}" aria-label="Clear the select contents">&nbsp;</button>
comboBoxEl.insertAdjacentHTML("beforeend", Sanitizer.escapeHTML`
<span class="${CLEAR_INPUT_BUTTON_WRAPPER_CLASS}" tabindex="-1">
<button type="button" class="${CLEAR_INPUT_BUTTON_CLASS}" aria-label="Clear the select contents">&nbsp;</button>
<button type="button" class="${CLEAR_INPUT_BUTTON_CLASS}" aria-label="Reset selection">&nbsp;</button>
</span>
<span class="${INPUT_BUTTON_SEPARATOR_CLASS}">&nbsp;</span>
<span class="${TOGGLE_LIST_BUTTON_WRAPPER_CLASS}" tabindex="-1">
@ -1356,8 +1360,12 @@ const displayList = el => {
for (let i = 0, len = selectEl.options.length; i < len; i += 1) {
const optionEl = selectEl.options[i];
const optionId = `${listOptionBaseId}${options.length}`;
if (optionEl.value && (disableFiltering || isPristine || !inputValue || regex.test(optionEl.text))) {
if (selectEl.value && optionEl.value === selectEl.value) {
// DOTGOV: modified combobox to allow for options with blank value
//if (optionEl.value && (disableFiltering || isPristine || !inputValue || regex.test(optionEl.text))) {
if ((disableFiltering || isPristine || !inputValue || regex.test(optionEl.text))) {
// DOTGOV: modified combobox to allow blank option value selections to be considered selected
//if (selectEl.value && optionEl.value === selectEl.value) {
if (selectEl.value && optionEl.value === selectEl.value || (!selectEl.value && !optionEl.value)) {
selectedItemId = optionId;
}
if (disableFiltering && !firstFoundId && regex.test(optionEl.text)) {

View file

@ -28,19 +28,6 @@ export function loadInitialValuesForComboBoxes() {
// Override the default clear button behavior such that it no longer clears the input,
// it just resets to the data-initial-value.
// 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 = comboBox.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);
// Input event listener to detect typing
input.addEventListener("input", () => {
@ -87,27 +74,4 @@ export function loadInitialValuesForComboBoxes() {
showElement(clearInputButton)
}
}
function addBlankOption(clearInputButton, dropdownList, initialValue) {
if (dropdownList && !dropdownList.querySelector('[data-value=""]') && !isTyping) {
const blankOption = document.createElement("li");
blankOption.setAttribute("role", "option");
blankOption.setAttribute("data-value", "");
blankOption.classList.add("usa-combo-box__list-option");
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;
});
}
}
}

View file

@ -164,6 +164,7 @@ class DomainSuborganizationForm(forms.ModelForm):
sub_organization = forms.ModelChoiceField(
label="Suborganization name",
queryset=Suborganization.objects.none(),
empty_label="⎯ (No suborganization)",
required=False,
widget=ComboboxWidget,
)
@ -468,12 +469,11 @@ class DomainOrgNameAddressForm(forms.ModelForm):
state_territory = forms.ChoiceField(
label="State, territory, or military post",
required=True,
choices=DomainInformation.StateTerritoryChoices.choices,
widget=ComboboxWidget(
attrs={
"required": True,
}
),
choices=[("", "--Select--")] + DomainInformation.StateTerritoryChoices.choices,
error_messages={
"required": ("Select the state, territory, or military post where your organization is located.")
},
widget=ComboboxWidget(),
)
class Meta:
@ -493,9 +493,6 @@ class DomainOrgNameAddressForm(forms.ModelForm):
"organization_name": {"required": "Enter the name of your organization."},
"address_line1": {"required": "Enter the street address of your organization."},
"city": {"required": "Enter the city where your organization is located."},
"state_territory": {
"required": "Select the state, territory, or military post where your organization is located."
},
}
widgets = {
"organization_name": forms.TextInput,

View file

@ -37,7 +37,10 @@ class PortfolioOrgAddressForm(forms.ModelForm):
state_territory = forms.ChoiceField(
label="State, territory, or military post",
required=True,
choices=DomainInformation.StateTerritoryChoices.choices,
choices=[("", "--Select--")] + DomainInformation.StateTerritoryChoices.choices,
error_messages={
"required": ("Select the state, territory, or military post where your organization is located.")
},
widget=ComboboxWidget,
)
@ -54,9 +57,6 @@ class PortfolioOrgAddressForm(forms.ModelForm):
error_messages = {
"address_line1": {"required": "Enter the street address of your organization."},
"city": {"required": "Enter the city where your organization is located."},
"state_territory": {
"required": "Select the state, territory, or military post where your organization is located."
},
"zipcode": {"required": "Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789."},
}
widgets = {