mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-14 16:47:02 +02:00
Updated Anything Else page to Additional Details page
This commit is contained in:
parent
6d13614521
commit
8f27aa1010
10 changed files with 314 additions and 71 deletions
|
@ -369,7 +369,7 @@ function enableRelatedWidgetButtons(changeLink, deleteLink, viewLink, elementPk,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An IIFE for admin in DjangoAdmin to listen to changes on the domain request
|
/** An IIFE for admin in DjangoAdmin to listen to changes on the domain request
|
||||||
* status select amd to show/hide the rejection reason
|
* status select and to show/hide the rejection reason
|
||||||
*/
|
*/
|
||||||
(function (){
|
(function (){
|
||||||
let rejectionReasonFormGroup = document.querySelector('.field-rejection_reason')
|
let rejectionReasonFormGroup = document.querySelector('.field-rejection_reason')
|
||||||
|
|
|
@ -193,6 +193,65 @@ function clearValidators(el) {
|
||||||
toggleInputValidity(el, true);
|
toggleInputValidity(el, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Hookup listeners for yes/no togglers for form fields
|
||||||
|
* Parameters:
|
||||||
|
* - radioButtonName: The "name=" value for the radio buttons being used as togglers
|
||||||
|
* - elementIdToShowIfYes: The Id of the element (eg. a div) to show if selected value of the given
|
||||||
|
* radio button is true (hides this element if false)
|
||||||
|
* - elementIdToShowIfNo: The Id of the element (eg. a div) to show if selected value of the given
|
||||||
|
* radio button is false (hides this element if true)
|
||||||
|
* **/
|
||||||
|
function HookupYesNoListener(radioButtonName, elementIdToShowIfYes, elementIdToShowIfNo) {
|
||||||
|
// Get the radio buttons
|
||||||
|
let radioButtons = document.querySelectorAll('input[name="'+radioButtonName+'"]');
|
||||||
|
|
||||||
|
function handleRadioButtonChange() {
|
||||||
|
// Check the value of the selected radio button
|
||||||
|
// Attempt to find the radio button element that is checked
|
||||||
|
let radioButtonChecked = document.querySelector('input[name="'+radioButtonName+'"]:checked');
|
||||||
|
|
||||||
|
// Check if the element exists before accessing its value
|
||||||
|
let selectedValue = radioButtonChecked ? radioButtonChecked.value : null;
|
||||||
|
|
||||||
|
switch (selectedValue) {
|
||||||
|
case 'True':
|
||||||
|
toggleTwoDomElements(elementIdToShowIfYes, elementIdToShowIfNo, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'False':
|
||||||
|
toggleTwoDomElements(elementIdToShowIfYes, elementIdToShowIfNo, 2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
toggleTwoDomElements(elementIdToShowIfYes, elementIdToShowIfNo, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (radioButtons.length) {
|
||||||
|
// Add event listener to each radio button
|
||||||
|
radioButtons.forEach(function (radioButton) {
|
||||||
|
radioButton.addEventListener('change', handleRadioButtonChange);
|
||||||
|
});
|
||||||
|
|
||||||
|
// initialize
|
||||||
|
handleRadioButtonChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A generic display none/block toggle function that takes an integer param to indicate how the elements toggle
|
||||||
|
function toggleTwoDomElements(ele1, ele2, index) {
|
||||||
|
let element1 = document.getElementById(ele1);
|
||||||
|
let element2 = document.getElementById(ele2);
|
||||||
|
if (element1 || element2) {
|
||||||
|
// Toggle display based on the index
|
||||||
|
if (element1) {element1.style.display = index === 1 ? 'block' : 'none';}
|
||||||
|
if (element2) {element2.style.display = index === 2 ? 'block' : 'none';}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.error('Unable to find elements to toggle');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// <<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
|
// <<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
|
||||||
// Event handlers.
|
// Event handlers.
|
||||||
|
|
||||||
|
@ -712,57 +771,29 @@ function hideDeletedForms() {
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// A generic display none/block toggle function that takes an integer param to indicate how the elements toggle
|
|
||||||
function toggleTwoDomElements(ele1, ele2, index) {
|
|
||||||
let element1 = document.getElementById(ele1);
|
|
||||||
let element2 = document.getElementById(ele2);
|
|
||||||
if (element1 && element2) {
|
|
||||||
// Toggle display based on the index
|
|
||||||
element1.style.display = index === 1 ? 'block' : 'none';
|
|
||||||
element2.style.display = index === 2 ? 'block' : 'none';
|
|
||||||
} else {
|
|
||||||
console.error('One or both elements not found.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An IIFE that listens to the other contacts radio form on DAs and toggles the contacts/no other contacts forms
|
* An IIFE that listens to the other contacts radio form on DAs and toggles the contacts/no other contacts forms
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
(function otherContactsFormListener() {
|
(function otherContactsFormListener() {
|
||||||
// Get the radio buttons
|
HookupYesNoListener("other_contacts-has_other_contacts",'other-employees', 'no-other-employees')
|
||||||
let radioButtons = document.querySelectorAll('input[name="other_contacts-has_other_contacts"]');
|
|
||||||
|
|
||||||
function handleRadioButtonChange() {
|
|
||||||
// Check the value of the selected radio button
|
|
||||||
// Attempt to find the radio button element that is checked
|
|
||||||
let radioButtonChecked = document.querySelector('input[name="other_contacts-has_other_contacts"]:checked');
|
|
||||||
|
|
||||||
// Check if the element exists before accessing its value
|
|
||||||
let selectedValue = radioButtonChecked ? radioButtonChecked.value : null;
|
|
||||||
|
|
||||||
switch (selectedValue) {
|
|
||||||
case 'True':
|
|
||||||
toggleTwoDomElements('other-employees', 'no-other-employees', 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'False':
|
|
||||||
toggleTwoDomElements('other-employees', 'no-other-employees', 2);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
toggleTwoDomElements('other-employees', 'no-other-employees', 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (radioButtons.length) {
|
|
||||||
// Add event listener to each radio button
|
|
||||||
radioButtons.forEach(function (radioButton) {
|
|
||||||
radioButton.addEventListener('change', handleRadioButtonChange);
|
|
||||||
});
|
|
||||||
|
|
||||||
// initialize
|
|
||||||
handleRadioButtonChange();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IIFE that listens to the yes/no radio buttons on the anything else form and toggles form field visibility accordingly
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
(function anythingElseFormListener() {
|
||||||
|
HookupYesNoListener("anything_else-has_anything_else_text",'anything-else', null)
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IIFE that listens to the yes/no radio buttons on the CISA representatives form and toggles form field visibility accordingly
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
(function cisaRepresentativesFormListener() {
|
||||||
|
HookupYesNoListener("anything_else-has_cisa_representative",'cisa-representative', null)
|
||||||
|
})();
|
|
@ -46,7 +46,7 @@ for step, view in [
|
||||||
(Step.PURPOSE, views.Purpose),
|
(Step.PURPOSE, views.Purpose),
|
||||||
(Step.YOUR_CONTACT, views.YourContact),
|
(Step.YOUR_CONTACT, views.YourContact),
|
||||||
(Step.OTHER_CONTACTS, views.OtherContacts),
|
(Step.OTHER_CONTACTS, views.OtherContacts),
|
||||||
(Step.ANYTHING_ELSE, views.AnythingElse),
|
(Step.ANYTHING_ELSE, views.AdditionalDetails),
|
||||||
(Step.REQUIREMENTS, views.Requirements),
|
(Step.REQUIREMENTS, views.Requirements),
|
||||||
(Step.REVIEW, views.Review),
|
(Step.REVIEW, views.Review),
|
||||||
]:
|
]:
|
||||||
|
|
|
@ -757,28 +757,15 @@ OtherContactsFormSet = forms.formset_factory(
|
||||||
formset=BaseOtherContactsFormSet,
|
formset=BaseOtherContactsFormSet,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class BaseDeletableRegistrarForm(RegistrarForm):
|
||||||
class NoOtherContactsForm(RegistrarForm):
|
"""Adds special validation and delete functionality.
|
||||||
no_other_contacts_rationale = forms.CharField(
|
Used by forms that are tied to a Yes/No form."""
|
||||||
required=True,
|
|
||||||
# label has to end in a space to get the label_suffix to show
|
|
||||||
label=("No other employees rationale"),
|
|
||||||
widget=forms.Textarea(),
|
|
||||||
validators=[
|
|
||||||
MaxLengthValidator(
|
|
||||||
1000,
|
|
||||||
message="Response must be less than 1000 characters.",
|
|
||||||
)
|
|
||||||
],
|
|
||||||
error_messages={"required": ("Rationale for no other employees is required.")},
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.form_data_marked_for_deletion = False
|
self.form_data_marked_for_deletion = False
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def mark_form_for_deletion(self):
|
def mark_form_for_deletion(self):
|
||||||
"""Marks no_other_contacts form for deletion.
|
"""Marks this form for deletion.
|
||||||
This changes behavior of validity checks and to_database
|
This changes behavior of validity checks and to_database
|
||||||
methods."""
|
methods."""
|
||||||
self.form_data_marked_for_deletion = True
|
self.form_data_marked_for_deletion = True
|
||||||
|
@ -822,8 +809,53 @@ class NoOtherContactsForm(RegistrarForm):
|
||||||
setattr(obj, name, value)
|
setattr(obj, name, value)
|
||||||
obj.save()
|
obj.save()
|
||||||
|
|
||||||
|
class NoOtherContactsForm(BaseDeletableRegistrarForm):
|
||||||
|
no_other_contacts_rationale = forms.CharField(
|
||||||
|
required=True,
|
||||||
|
# label has to end in a space to get the label_suffix to show
|
||||||
|
label=("No other employees rationale"),
|
||||||
|
widget=forms.Textarea(),
|
||||||
|
validators=[
|
||||||
|
MaxLengthValidator(
|
||||||
|
1000,
|
||||||
|
message="Response must be less than 1000 characters.",
|
||||||
|
)
|
||||||
|
],
|
||||||
|
error_messages={"required": ("Rationale for no other employees is required.")},
|
||||||
|
)
|
||||||
|
|
||||||
class AnythingElseForm(RegistrarForm):
|
class CisaRepresentativeForm(BaseDeletableRegistrarForm):
|
||||||
|
cisa_representative_email = forms.EmailField(
|
||||||
|
required=False,
|
||||||
|
label="Are you working with a CISA representative?", #TODO-NL: (design check) - is this the right label?
|
||||||
|
)
|
||||||
|
|
||||||
|
class CisaRepresentativeYesNoForm(RegistrarForm):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
"""Extend the initialization of the form from RegistrarForm __init__"""
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
# set the initial value based on attributes of domain request
|
||||||
|
if self.domain_request:
|
||||||
|
if self.domain_request.has_cisa_representative():
|
||||||
|
initial_value = True
|
||||||
|
else:
|
||||||
|
initial_value = False
|
||||||
|
else:
|
||||||
|
# No pre-selection for new domain requests
|
||||||
|
initial_value = None
|
||||||
|
|
||||||
|
self.fields["has_cisa_representative"] = forms.TypedChoiceField(
|
||||||
|
coerce=lambda x: x.lower() == "true" if x is not None else None, # coerce strings to bool, excepting None
|
||||||
|
choices=((True, "Yes"), (False, "No")),
|
||||||
|
initial=initial_value,
|
||||||
|
widget=forms.RadioSelect,
|
||||||
|
error_messages={
|
||||||
|
"required": "This question is required.",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AdditionalDetailsForm(BaseDeletableRegistrarForm):
|
||||||
anything_else = forms.CharField(
|
anything_else = forms.CharField(
|
||||||
required=False,
|
required=False,
|
||||||
label="Anything else?",
|
label="Anything else?",
|
||||||
|
@ -836,6 +868,29 @@ class AnythingElseForm(RegistrarForm):
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class AdditionalDetailsYesNoForm(RegistrarForm):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
"""Extend the initialization of the form from RegistrarForm __init__"""
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
# set the initial value based on attributes of domain request
|
||||||
|
if self.domain_request:
|
||||||
|
if self.domain_request.has_anything_else_text():
|
||||||
|
initial_value = True
|
||||||
|
else:
|
||||||
|
initial_value = False
|
||||||
|
else:
|
||||||
|
# No pre-selection for new domain requests
|
||||||
|
initial_value = None
|
||||||
|
|
||||||
|
self.fields["has_anything_else_text"] = forms.TypedChoiceField(
|
||||||
|
coerce=lambda x: x.lower() == "true" if x is not None else None, # coerce strings to bool, excepting None
|
||||||
|
choices=((True, "Yes"), (False, "No")),
|
||||||
|
initial=initial_value,
|
||||||
|
widget=forms.RadioSelect,
|
||||||
|
error_messages={
|
||||||
|
"required": "This question is required.", #TODO-NL: (design check) - is this required?
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
class RequirementsForm(RegistrarForm):
|
class RequirementsForm(RegistrarForm):
|
||||||
is_policy_acknowledged = forms.BooleanField(
|
is_policy_acknowledged = forms.BooleanField(
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Generated by Django 4.2.10 on 2024-04-10 22:19
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("registrar", "0081_create_groups_v10"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="domaininformation",
|
||||||
|
name="cisa_representative_email",
|
||||||
|
field=models.EmailField(blank=True, db_index=True, max_length=254, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="domainrequest",
|
||||||
|
name="cisa_representative_email",
|
||||||
|
field=models.EmailField(blank=True, db_index=True, max_length=254, null=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -198,6 +198,12 @@ class DomainInformation(TimeStampedModel):
|
||||||
help_text="Anything else?",
|
help_text="Anything else?",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
cisa_representative_email = models.EmailField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
db_index=True,
|
||||||
|
)
|
||||||
|
|
||||||
is_policy_acknowledged = models.BooleanField(
|
is_policy_acknowledged = models.BooleanField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
|
|
@ -566,6 +566,12 @@ class DomainRequest(TimeStampedModel):
|
||||||
help_text="Anything else?",
|
help_text="Anything else?",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
cisa_representative_email = models.EmailField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
db_index=True,
|
||||||
|
)
|
||||||
|
|
||||||
is_policy_acknowledged = models.BooleanField(
|
is_policy_acknowledged = models.BooleanField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
@ -924,6 +930,14 @@ class DomainRequest(TimeStampedModel):
|
||||||
"""Does this domain request have other contacts listed?"""
|
"""Does this domain request have other contacts listed?"""
|
||||||
return self.other_contacts.exists()
|
return self.other_contacts.exists()
|
||||||
|
|
||||||
|
def has_anything_else_text(self) -> bool:
|
||||||
|
"""Does this domain request have an 'anything else?' entry"""
|
||||||
|
return self.anything_else != "" and self.anything_else != None #TODO-NL: how to handle falsy strings again?
|
||||||
|
|
||||||
|
def has_cisa_representative(self) -> bool:
|
||||||
|
"""Does this domain request have cisa representative?"""
|
||||||
|
return self.cisa_representative_email != "" and self.cisa_representative_email != None
|
||||||
|
|
||||||
def is_federal(self) -> Union[bool, None]:
|
def is_federal(self) -> Union[bool, None]:
|
||||||
"""Is this domain request for a federal agency?
|
"""Is this domain request for a federal agency?
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
{% extends 'domain_request_form.html' %}
|
||||||
|
{% load static field_helpers %}
|
||||||
|
|
||||||
|
{% block form_instructions %}
|
||||||
|
<p><i>These questions are required (*).</i></p>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block form_required_fields_help_text %}
|
||||||
|
{# commented out so it does not appear at this point on this page #}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
<!-- TODO-NL: (refactor) Breakup into two separate components-->
|
||||||
|
{% block form_fields %}
|
||||||
|
<fieldset class="usa-fieldset margin-top-2">
|
||||||
|
<legend>
|
||||||
|
<h2>Are you working with anyone from CISA regions on your domain request?</h2>
|
||||||
|
<p>.gov is managed by the Cybersecurity and Infrastructure Security Agency. CISA has 10 regions that some organizations choose to work with. Regional representatives use titles like protective security advisors, cyber security advisors, or election security advisors.</p>
|
||||||
|
</legend>
|
||||||
|
|
||||||
|
<!-- Toggle -->
|
||||||
|
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||||
|
{% input_with_errors forms.0.has_cisa_representative %}
|
||||||
|
{% endwith %}
|
||||||
|
{# forms.0 is a small yes/no form that toggles the visibility of "cisa representative" formset #}
|
||||||
|
<!-- TODO-NL: Hookup forms.0 to yes/no form for cisa representative (backend def)-->
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<div id="cisa-representative" class="cisa-representative-form">
|
||||||
|
<p>Your representative’s email (*)</p>
|
||||||
|
{% input_with_errors forms.1.cisa_representative_email %}
|
||||||
|
{# forms.1 is a form for inputting the e-mail of a cisa representative #}
|
||||||
|
<!-- TODO-NL: Hookup forms.1 to cisa representative form (backend def) -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<fieldset class="usa-fieldset margin-top-2">
|
||||||
|
<legend>
|
||||||
|
<h2>Is there anything else you’d like us to know about your domain request?</h2>
|
||||||
|
</legend>
|
||||||
|
|
||||||
|
<!-- Toggle -->
|
||||||
|
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||||
|
{% input_with_errors forms.2.has_anything_else_text %}
|
||||||
|
{% endwith %}
|
||||||
|
{# forms.2 is a small yes/no form that toggles the visibility of "cisa representative" formset #}
|
||||||
|
<!-- TODO-NL: Hookup forms.2 to yes/no form for anything else form (backend def)-->
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<div id="anything-else">
|
||||||
|
{% with attr_maxlength=2000 add_label_class="usa-sr-only" %}
|
||||||
|
{% input_with_errors forms.3.anything_else %}
|
||||||
|
{% endwith %}
|
||||||
|
{# forms.3 is a form for inputting the e-mail of a cisa representative #}
|
||||||
|
<!-- TODO-NL: Hookup forms.3 to anything else form (backend def) -->
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -15,7 +15,7 @@ from registrar.forms.domain_request_wizard import (
|
||||||
RequirementsForm,
|
RequirementsForm,
|
||||||
TribalGovernmentForm,
|
TribalGovernmentForm,
|
||||||
PurposeForm,
|
PurposeForm,
|
||||||
AnythingElseForm,
|
AdditionalDetailsForm,
|
||||||
AboutYourOrganizationForm,
|
AboutYourOrganizationForm,
|
||||||
)
|
)
|
||||||
from registrar.forms.domain import ContactForm
|
from registrar.forms.domain import ContactForm
|
||||||
|
@ -274,7 +274,7 @@ class TestFormValidation(MockEppLib):
|
||||||
|
|
||||||
def test_anything_else_form_about_your_organization_character_count_invalid(self):
|
def test_anything_else_form_about_your_organization_character_count_invalid(self):
|
||||||
"""Response must be less than 2000 characters."""
|
"""Response must be less than 2000 characters."""
|
||||||
form = AnythingElseForm(
|
form = AdditionalDetailsForm(
|
||||||
data={
|
data={
|
||||||
"anything_else": "Bacon ipsum dolor amet fatback strip steak pastrami"
|
"anything_else": "Bacon ipsum dolor amet fatback strip steak pastrami"
|
||||||
"shankle, drumstick doner chicken landjaeger turkey andouille."
|
"shankle, drumstick doner chicken landjaeger turkey andouille."
|
||||||
|
|
|
@ -580,10 +580,68 @@ class OtherContacts(DomainRequestWizard):
|
||||||
all_forms_valid = False
|
all_forms_valid = False
|
||||||
return all_forms_valid
|
return all_forms_valid
|
||||||
|
|
||||||
|
#DONE-NL: rename this to "Additional Details" (note: this is a find-replace job. VS will not refactor properly)
|
||||||
|
class AdditionalDetails(DomainRequestWizard):
|
||||||
|
|
||||||
class AnythingElse(DomainRequestWizard):
|
# TODO-NL: Delete this old (original code for anything else)
|
||||||
template_name = "domain_request_anything_else.html"
|
# template_name = "domain_request_anything_else.html"
|
||||||
forms = [forms.AnythingElseForm]
|
# forms = [forms.AdditionalDetailsForm]
|
||||||
|
|
||||||
|
template_name = "domain_request_additional_details.html"
|
||||||
|
# OLD: forms = [forms.OtherContactsYesNoForm, forms.OtherContactsFormSet, forms.NoOtherContactsForm]
|
||||||
|
# TODO-NL: (refactor) -- move form hookups into respective areas
|
||||||
|
forms = [forms.CisaRepresentativeYesNoForm, forms.CisaRepresentativeForm, forms.AdditionalDetailsYesNoForm, forms.AdditionalDetailsForm]
|
||||||
|
|
||||||
|
# TODO-NL: (refactor) -- move validation into respective areas
|
||||||
|
def is_valid(self, forms: list) -> bool:
|
||||||
|
|
||||||
|
# Validate Cisa Representative
|
||||||
|
"""Overrides default behavior defined in DomainRequestWizard.
|
||||||
|
Depending on value in yes_no forms, marks corresponding data
|
||||||
|
for deletion. Then validates all forms.
|
||||||
|
"""
|
||||||
|
cisa_representative_email_yes_no_form = forms[0]
|
||||||
|
cisa_representative_email_form = forms[1]
|
||||||
|
anything_else_yes_no_form = forms[2]
|
||||||
|
anything_else_form = forms[3]
|
||||||
|
|
||||||
|
# ------- Validate cisa representative -------
|
||||||
|
cisa_rep_portion_is_valid = True
|
||||||
|
# test first for yes_no_form validity
|
||||||
|
if cisa_representative_email_yes_no_form.is_valid():
|
||||||
|
# test for existing data
|
||||||
|
if not cisa_representative_email_yes_no_form.cleaned_data.get("has_cisa_representative"):
|
||||||
|
# mark the cisa_representative_email_form for deletion
|
||||||
|
cisa_representative_email_form.mark_form_for_deletion()
|
||||||
|
else:
|
||||||
|
cisa_rep_portion_is_valid = cisa_representative_email_form.is_valid()
|
||||||
|
else:
|
||||||
|
# if yes no form is invalid, no choice has been made
|
||||||
|
# mark the cisa_representative_email_form for deletion
|
||||||
|
cisa_representative_email_form.mark_form_for_deletion()
|
||||||
|
cisa_rep_portion_is_valid = False
|
||||||
|
|
||||||
|
|
||||||
|
# ------- Validate anything else -------
|
||||||
|
anything_else_portion_is_valid = True
|
||||||
|
# test first for yes_no_form validity
|
||||||
|
if anything_else_yes_no_form.is_valid():
|
||||||
|
# test for existing data
|
||||||
|
if not anything_else_yes_no_form.cleaned_data.get("has_anything_else_text"):
|
||||||
|
# mark the anything_else_form for deletion
|
||||||
|
anything_else_form.mark_form_for_deletion()
|
||||||
|
else:
|
||||||
|
anything_else_portion_is_valid = cisa_representative_email_form.is_valid()
|
||||||
|
else:
|
||||||
|
# if yes no form is invalid, no choice has been made
|
||||||
|
# mark the anything_else_form for deletion
|
||||||
|
anything_else_form.mark_form_for_deletion()
|
||||||
|
anything_else_portion_is_valid = False
|
||||||
|
|
||||||
|
|
||||||
|
# ------- Return combined validation result -------
|
||||||
|
all_forms_valid = cisa_rep_portion_is_valid and anything_else_portion_is_valid
|
||||||
|
return all_forms_valid
|
||||||
|
|
||||||
|
|
||||||
class Requirements(DomainRequestWizard):
|
class Requirements(DomainRequestWizard):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue