diff --git a/src/registrar/assets/js/uswds-edited.js b/src/registrar/assets/js/uswds-edited.js
index 60502050f..9e3922c9c 100644
--- a/src/registrar/assets/js/uswds-edited.js
+++ b/src/registrar/assets/js/uswds-edited.js
@@ -1038,7 +1038,7 @@ const noop = () => {};
* @param {string} value The new value of the element
*/
const changeElementValue = function (el) {
- let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
+ let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
const elementToChange = el;
elementToChange.value = value;
const event = new CustomEvent("change", {
@@ -1168,22 +1168,14 @@ const enhanceComboBox = _comboBoxEl => {
placeholder
});
}
- // DOTGOV - allowing for defaultValue to be empty
- //if (defaultValue) {
- // for (let i = 0, len = selectEl.options.length; i < len; i += 1) {
- // const optionEl = selectEl.options[i];
- // if (optionEl.value === defaultValue) {
- // selectedOption = optionEl;
- // break;
- // }
- // }
- //}
- for (let i = 0, len = selectEl.options.length; i < len; i += 1) {
- const optionEl = selectEl.options[i];
- if ((optionEl.value === defaultValue) || (!optionEl.value && !defaultValue)) {
- selectedOption = optionEl;
- break;
- }
+ if (defaultValue) {
+ for (let i = 0, len = selectEl.options.length; i < len; i += 1) {
+ const optionEl = selectEl.options[i];
+ if (optionEl.value === defaultValue) {
+ selectedOption = optionEl;
+ break;
+ }
+ }
}
/**
@@ -1234,11 +1226,9 @@ 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
- //
comboBoxEl.insertAdjacentHTML("beforeend", Sanitizer.escapeHTML`
-
+
@@ -1374,12 +1364,8 @@ 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}`;
- // 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)) {
+ if (optionEl.value && (disableFiltering || isPristine || !inputValue || regex.test(optionEl.text))) {
+ if (selectEl.value && optionEl.value === selectEl.value) {
selectedItemId = optionId;
}
if (disableFiltering && !firstFoundId && regex.test(optionEl.text)) {
@@ -1514,28 +1500,17 @@ const resetSelection = el => {
} = getComboBoxContext(el);
const selectValue = selectEl.value;
const inputValue = (inputEl.value || "").toLowerCase();
- // DOTGOV - allow for option value to be empty string
- //if (selectValue) {
- // for (let i = 0, len = selectEl.options.length; i < len; i += 1) {
- // const optionEl = selectEl.options[i];
- // if (optionEl.value === selectValue) {
- // if (inputValue !== optionEl.text) {
- // changeElementValue(inputEl, optionEl.text);
- // }
- // comboBoxEl.classList.add(COMBO_BOX_PRISTINE_CLASS);
- // return;
- // }
- // }
- //}
- for (let i = 0, len = selectEl.options.length; i < len; i += 1) {
- const optionEl = selectEl.options[i];
- if ((!selectValue && !optionEl.value) || optionEl.value === selectValue) {
- if (inputValue !== optionEl.text) {
- changeElementValue(inputEl, optionEl.text);
- }
- comboBoxEl.classList.add(COMBO_BOX_PRISTINE_CLASS);
- return;
- }
+ if (selectValue) {
+ for (let i = 0, len = selectEl.options.length; i < len; i += 1) {
+ const optionEl = selectEl.options[i];
+ if (optionEl.value === selectValue) {
+ if (inputValue !== optionEl.text) {
+ changeElementValue(inputEl, optionEl.text);
+ }
+ comboBoxEl.classList.add(COMBO_BOX_PRISTINE_CLASS);
+ return;
+ }
+ }
}
if (inputValue) {
changeElementValue(inputEl);
diff --git a/src/registrar/assets/src/js/getgov/main.js b/src/registrar/assets/src/js/getgov/main.js
index 6ff402aa4..9f3156cf7 100644
--- a/src/registrar/assets/src/js/getgov/main.js
+++ b/src/registrar/assets/src/js/getgov/main.js
@@ -31,7 +31,7 @@ initializeUrbanizationToggle();
userProfileListener();
finishUserSetupListener();
-loadInitialValuesForComboBoxes();
+//loadInitialValuesForComboBoxes();
handleRequestingEntityFieldset();
diff --git a/src/registrar/forms/domain_request_wizard.py b/src/registrar/forms/domain_request_wizard.py
index 636a41760..e40355d61 100644
--- a/src/registrar/forms/domain_request_wizard.py
+++ b/src/registrar/forms/domain_request_wizard.py
@@ -77,6 +77,20 @@ class RequestingEntityForm(RegistrarForm):
(obj.id, str(obj)) for obj in queryset
] + [("other", "Other (enter your suborganization manually)")]
+ @classmethod
+ def from_database(cls, obj: DomainRequest | None):
+ """Returns a dict of form field values gotten from `obj`.
+ Overrides RegistrarForm method in order to set sub_organization to 'other'
+ on GETs of the RequestingEntityForm."""
+ if obj is None:
+ return {}
+ # get the domain request as a dict, per usual method
+ domain_request_dict = {name: getattr(obj, name) for name in cls.declared_fields.keys()} # type: ignore
+ # set sub_organization to 'other' if is_requesting_new_suborganization is True
+ if obj.is_requesting_new_suborganization():
+ domain_request_dict["sub_organization"] = "other"
+ return domain_request_dict
+
def clean_sub_organization(self):
"""On suborganization clean, set the suborganization value to None if the user is requesting
a custom suborganization (as it doesn't exist yet)"""
@@ -102,42 +116,132 @@ class RequestingEntityForm(RegistrarForm):
)
return name
+ # def full_clean(self):
+ # """Validation logic to remove the custom suborganization value before clean is triggered.
+ # Without this override, the form will throw an 'invalid option' error."""
+ # # Remove the custom other field before cleaning
+ # data = self.data.copy() if self.data else None
+
+ # # Remove the 'other' value from suborganization if it exists.
+ # # This is a special value that tracks if the user is requesting a new suborg.
+ # suborganization = self.data.get("portfolio_requesting_entity-sub_organization")
+ # if suborganization and "other" in suborganization:
+ # data["portfolio_requesting_entity-sub_organization"] = ""
+
+ # # Set the modified data back to the form
+ # self.data = data
+
+ # # Call the parent's full_clean method
+ # super().full_clean()
+
def full_clean(self):
- """Validation logic to remove the custom suborganization value before clean is triggered.
+ """Validation logic to temporarily remove the custom suborganization value before clean is triggered.
Without this override, the form will throw an 'invalid option' error."""
- # Remove the custom other field before cleaning
- data = self.data.copy() if self.data else None
+ logger.debug("full_clean")
+ # Ensure self.data is not None before proceeding
+ if self.data:
+ # handle case where form has been submitted
+ logger.debug("form was submitted")
+ # Create a copy of the data for manipulation
+ data = self.data.copy()
- # Remove the 'other' value from suborganization if it exists.
- # This is a special value that tracks if the user is requesting a new suborg.
- suborganization = self.data.get("portfolio_requesting_entity-sub_organization")
- if suborganization and "other" in suborganization:
- data["portfolio_requesting_entity-sub_organization"] = ""
+ # Retrieve sub_organization
+ suborganization = data.get("portfolio_requesting_entity-sub_organization")
- # Set the modified data back to the form
- self.data = data
+ logger.debug(f"suborganization submitted as {suborganization}")
+ # # Determine if "other" should be stored in _original_suborganization
+ # if not suborganization:
+ # logger.debug("suborg stored as other")
+ # self._original_suborganization = "other"
+ # else:
+ self._original_suborganization = suborganization
+
+ # If the original value was "other", clear it for validation
+ if self._original_suborganization == "other":
+ data["portfolio_requesting_entity-sub_organization"] = ""
+
+ # Set the modified data back to the form
+ self.data = data
+ else:
+ # handle case of a GET
+ suborganization = None
+ if self.initial and "sub_organization" in self.initial:
+ print("suborg in self.initial")
+ suborganization = self.initial["sub_organization"]
+ print(self.initial["sub_organization"])
+ print(suborganization)
+ # Check if is_requesting_new_suborganization is True
+ is_requesting_new_suborganization = False
+ if self.initial and "is_requesting_new_suborganization" in self.initial:
+ # Call the method if it exists
+ print(self.initial["is_requesting_new_suborganization"]())
+ is_requesting_new_suborganization = self.initial["is_requesting_new_suborganization"]()
+
+ # Determine if "other" should be set
+ if is_requesting_new_suborganization and suborganization is None:
+ print("presetting to other")
+ self._original_suborganization = "other"
+ else:
+ self._original_suborganization = suborganization
+ print("self.data does not exist")
+ print(self.initial)
+ # # Handle the initial GET request case
+ # self._original_suborganization = None
# Call the parent's full_clean method
super().full_clean()
+ # Restore "other" if there are errors
+ if self.errors:
+ logger.debug(f"errors detected: {self.errors}; resetting original_sub_organization")
+ self.data["portfolio_requesting_entity-sub_organization"] = self._original_suborganization
+
+
+ # def clean(self):
+ # """Custom clean implementation to handle our desired logic flow for suborganization.
+ # Given that these fields often rely on eachother, we need to do this in the parent function."""
+ # cleaned_data = super().clean()
+
+ # # Do some custom error validation if the requesting entity is a suborg.
+ # # Otherwise, just validate as normal.
+ # suborganization = self.cleaned_data.get("sub_organization")
+ # is_requesting_new_suborganization = self.cleaned_data.get("is_requesting_new_suborganization")
+
+ # # Get the value of the yes/no checkbox from RequestingEntityYesNoForm.
+ # # Since self.data stores this as a string, we need to convert "True" => True.
+ # requesting_entity_is_suborganization = self.data.get(
+ # "portfolio_requesting_entity-requesting_entity_is_suborganization"
+ # )
+ # if requesting_entity_is_suborganization == "True":
+ # if is_requesting_new_suborganization:
+ # # Validate custom suborganization fields
+ # if not cleaned_data.get("requested_suborganization") and "requested_suborganization" not in self.errors:
+ # self.add_error("requested_suborganization", "Enter the name of your suborganization.")
+ # if not cleaned_data.get("suborganization_city"):
+ # self.add_error("suborganization_city", "Enter the city where your suborganization is located.")
+ # if not cleaned_data.get("suborganization_state_territory"):
+ # self.add_error(
+ # "suborganization_state_territory",
+ # "Select the state, territory, or military post where your suborganization is located.",
+ # )
+ # elif not suborganization:
+ # self.add_error("sub_organization", "Suborganization is required.")
+
+ # return cleaned_data
+
def clean(self):
- """Custom clean implementation to handle our desired logic flow for suborganization.
- Given that these fields often rely on eachother, we need to do this in the parent function."""
+ """Custom clean implementation to handle our desired logic flow for suborganization."""
cleaned_data = super().clean()
- # Do some custom error validation if the requesting entity is a suborg.
- # Otherwise, just validate as normal.
- suborganization = self.cleaned_data.get("sub_organization")
- is_requesting_new_suborganization = self.cleaned_data.get("is_requesting_new_suborganization")
-
- # Get the value of the yes/no checkbox from RequestingEntityYesNoForm.
- # Since self.data stores this as a string, we need to convert "True" => True.
+ # Get the cleaned data
+ suborganization = cleaned_data.get("sub_organization")
+ is_requesting_new_suborganization = cleaned_data.get("is_requesting_new_suborganization")
requesting_entity_is_suborganization = self.data.get(
"portfolio_requesting_entity-requesting_entity_is_suborganization"
)
+
if requesting_entity_is_suborganization == "True":
if is_requesting_new_suborganization:
- # Validate custom suborganization fields
if not cleaned_data.get("requested_suborganization") and "requested_suborganization" not in self.errors:
self.add_error("requested_suborganization", "Enter the name of your suborganization.")
if not cleaned_data.get("suborganization_city"):
@@ -150,6 +254,12 @@ class RequestingEntityForm(RegistrarForm):
elif not suborganization:
self.add_error("sub_organization", "Suborganization is required.")
+ # If there are errors, restore the "other" value for rendering
+ if self.errors and getattr(self, "_original_suborganization", None) == "other":
+ self.cleaned_data["sub_organization"] = self._original_suborganization
+ elif not self.data and getattr(self, "_original_suborganization", None) == "other":
+ self.cleaned_data["sub_organization"] = self._original_suborganization
+
return cleaned_data
diff --git a/src/registrar/views/domain_request.py b/src/registrar/views/domain_request.py
index 9754b0d0c..e0225aab3 100644
--- a/src/registrar/views/domain_request.py
+++ b/src/registrar/views/domain_request.py
@@ -368,7 +368,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
and from the database if `use_db` is True (provided that record exists).
An empty form will be provided if neither of those are true.
"""
-
+ logger.debug(f"get_forms({step},{use_post},{use_db},{files})")
kwargs = {
"files": files,
"prefix": self.steps.current,
@@ -385,6 +385,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
for form in forms:
data = form.from_database(self.domain_request) if self.has_pk() else None
+ logger.debug(data)
if use_post:
instantiated.append(form(self.request.POST, **kwargs))
elif use_db:
@@ -562,6 +563,13 @@ class RequestingEntity(DomainRequestWizard):
template_name = "domain_request_requesting_entity.html"
forms = [forms.RequestingEntityYesNoForm, forms.RequestingEntityForm]
+ #for debugging:
+ def get(self, request, *args, **kwargs):
+ """This method handles GET requests."""
+ logger.debug("in get")
+
+ return super().get(request, *args, **kwargs)
+
def save(self, forms: list):
"""Override of save to clear or associate certain suborganization data
depending on what the user wishes to do. For instance, we want to add a suborganization