push remote for demo

This commit is contained in:
matthewswspence 2025-02-28 12:54:51 -06:00
parent fb06683982
commit c821b20e8e
No known key found for this signature in database
GPG key ID: FB458202A7852BA4
6 changed files with 138 additions and 40 deletions

View file

@ -0,0 +1,44 @@
import { showElement } from './helpers.js';
export const domain_purpose_choice_callbacks = {
'new': {
callback: function(value, element) {
console.log("Callback for new")
//show the purpose details container
showElement(element);
// change just the text inside the em tag
const labelElement = element.querySelector('.usa-label em');
labelElement.innerHTML = 'Explain why a new domain is required and why a ' +
'subdomain of an existing domain doesn\'t meet your needs.' +
'<br><br>' + // Adding double line break for spacing
'Include any data that supports a clear public benefit or ' +
'evidence user need for this new domain. ' +
'<span class="usa-label--required">*</span>';
},
element: document.getElementById('domain-purpose-details-container')
},
'redirect': {
callback: function(value, element) {
console.log("Callback for redirect")
// show the purpose details container
showElement(element);
// change just the text inside the em tag
const labelElement = element.querySelector('.usa-label em');
labelElement.innerHTML = 'Explain why a redirect is necessary. ' +
'<span class="usa-label--required">*</span>';
},
element: document.getElementById('domain-purpose-details-container')
},
'other': {
callback: function(value, element) {
console.log("Callback for other")
// Show the purpose details container
showElement(element);
// change just the text inside the em tag
const labelElement = element.querySelector('.usa-label em');
labelElement.innerHTML = 'Describe how this domain will be used. ' +
'<span class="usa-label--required">*</span>';
},
element: document.getElementById('domain-purpose-details-container')
}
}

View file

@ -1,4 +1,4 @@
import { hookupYesNoListener, hookupRadioTogglerListener } from './radios.js';
import { hookupYesNoListener, hookupCallbacksToRadioToggler } from './radios.js';
import { initDomainValidators } from './domain-validators.js';
import { initFormsetsForms, triggerModalOnDsDataForm, nameserversFormListener } from './formset-forms.js';
import { initializeUrbanizationToggle } from './urbanization.js';
@ -15,7 +15,7 @@ import { initDomainManagersPage } from './domain-managers.js';
import { initDomainDSData } from './domain-dsdata.js';
import { initDomainDNSSEC } from './domain-dnssec.js';
import { initFormErrorHandling } from './form-errors.js';
import { domain_purpose_choice_callbacks } from './domain-purpose-form.js';
initDomainValidators();
initFormsetsForms();
@ -27,6 +27,12 @@ hookupYesNoListener("additional_details-has_anything_else_text",'anything-else',
hookupYesNoListener("additional_details-has_cisa_representative",'cisa-representative', null);
hookupYesNoListener("dotgov_domain-feb_naming_requirements", null, "domain-naming-requirements-details-container");
hookupCallbacksToRadioToggler("purpose-feb_purpose_choice", domain_purpose_choice_callbacks);
hookupYesNoListener("purpose-has_timeframe", "domain-timeframe-details-container", null);
hookupYesNoListener("purpose-is_interagency_initiative", "domain-interagency-initaitive-details-container", null);
initializeUrbanizationToggle();
userProfileListener();

View file

@ -17,7 +17,7 @@ export function hookupYesNoListener(radioButtonName, elementIdToShowIfYes, eleme
'False': elementIdToShowIfNo
});
}
/**
* Hookup listeners for radio togglers in form fields.
*
@ -75,3 +75,57 @@ export function hookupRadioTogglerListener(radioButtonName, valueToElementMap) {
handleRadioButtonChange();
}
}
/**
* Hookup listeners for radio togglers in form fields.
*
* Parameters:
* - radioButtonName: The "name=" value for the radio buttons being used as togglers
* - valueToCallbackMap: An object where keys are the values of the radio buttons,
* and values are dictionaries containing a 'callback' key and an optional 'element' key.
* If provided, the element will be passed in as the second argument to the callback function.
*
* Usage Example:
* Assuming you have radio buttons with values 'option1', 'option2', and 'option3',
* and corresponding callback functions 'function1', 'function2', 'function3' that will
* apply to elements 'element1', 'element2', 'element3' respectively.
*
* hookupCallbacksToRadioToggler('exampleRadioGroup', {
* 'option1': {callback: function1, element: element1},
* 'option2': {callback: function2, element: element2},
* 'option3': {callback: function3} // No element provided
* });
*
* Picking the 'option1' radio button will call function1('option1', element1).
* Picking the 'option3' radio button will call function3('option3') without a second parameter.
**/
export function hookupCallbacksToRadioToggler(radioButtonName, valueToCallbackMap) {
// Get the radio buttons
let radioButtons = document.querySelectorAll(`input[name="${radioButtonName}"]`);
function handleRadioButtonChange() {
// Find the checked radio button
let radioButtonChecked = document.querySelector(`input[name="${radioButtonName}"]:checked`);
let selectedValue = radioButtonChecked ? radioButtonChecked.value : null;
// Execute the callback function for the selected value
if (selectedValue && valueToCallbackMap[selectedValue]) {
const entry = valueToCallbackMap[selectedValue];
if ('element' in entry) {
entry.callback(selectedValue, entry.element);
} else {
entry.callback(selectedValue);
}
}
}
if (radioButtons && radioButtons.length) {
// Add event listener to each radio button
radioButtons.forEach(function (radioButton) {
radioButton.addEventListener('change', handleRadioButtonChange);
});
// Initialize by checking the current state
handleRadioButtonChange();
}
}

View file

@ -20,13 +20,6 @@ class FEBPurposeOptionsForm(BaseDeletableRegistrarForm):
class PurposeDetailsForm(BaseDeletableRegistrarForm):
labels = {
"new": "Explain why a new domain is required and why a subdomain of an existing domain doesn't meet your needs. \
Include any data that supports a clear public benefit or evident user need for this new domain.",
"redirect": "Explain why a redirect is necessary",
"other": "Describe how this domain will be used",
}
field_name="purpose"
purpose = forms.CharField(

View file

@ -7,10 +7,6 @@
<h2>What is the purpose of your requested domain?</h2>
{% endblock %}
{% block form_required_fields_help_text %}
{# commented out so it does not appear on this page #}
{% endblock %}
{% block form_fields %}
{% if requires_feb_questions %}
<fieldset class="usa-fieldset margin-top-0 dotgov-domain-form">
@ -21,60 +17,56 @@
{{forms.4.management_form}}
{{forms.5.management_form}}
<p class="usa-label">
Select One <span class="usa-label--required">*</span>
<em>Select One <span class="usa-label--required">*</span></em>
</p>
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
{% input_with_errors forms.0.feb_purpose_choice %}
{% endwith %}
<div id="domain-purpose-details-container" class="conditional-panel" style="display: none;">
<div id="domain-purpose-details-container" class="conditional-panel display-none">
<p class="usa-label">
Provide details below <span class="usa-label--required">*</span>
<em>Provide details below <span class="usa-label--required">*</span></em>
</p>
{% with add_label_class="usa-sr-only" attr_required="required" maxlength="2000" %}
{% input_with_errors forms.1.purpose %}
{% endwith %}
<p class="usa-hint">Maximum 2000 characters allowed.</p>
<p class="usa-hint margin-top-0">Maximum 2000 characters allowed.</p>
</div>
<legend>
<h3>Do you have a target time frame for launching this domain?</h3>
</legend>
<h2 class="margin-top-5">Do you have a target time frame for launching this domain?</h2>
<p class="usa-label">
Select One <span class="usa-label--required">*</span>
<em>Select One <span class="usa-label--required">*</span></em>
</p>
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
{% input_with_errors forms.2.has_timeframe %}
{% endwith %}
<div id="domain-timeframe-details-container" class="conditional-panel" style="display: none;">
<p class="usa-label">
Provide details below <span class="usa-label--required">*</span>
<div id="domain-timeframe-details-container" class="conditional-panel">
<p>
<em>Provide details below <span class="usa-label--required">*</span></em>
</p>
{% with add_label_class="usa-sr-only" attr_required="required" maxlength="2000" %}
{% input_with_errors forms.3.time_frame_details %}
{% endwith %}
<p class="usa-hint">Maximum 2000 characters allowed.</p>
<p class="usa-hint margin-top-0">Maximum 2000 characters allowed.</p>
</div>
<legend>
<h3>Will the domain name be used for an interagency initiative?</h3>
</legend>
<p class="usa-label">
Select One <span class="usa-label--required">*</span>
<h2>Will the domain name be used for an interagency initiative?</h2>
<p>
<em>Select One <span class="usa-label--required">*</span></em>
</p>
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
{% input_with_errors forms.4.is_interagency_initiative %}
{% endwith %}
<div id="domain-interagency-initaitive-details-container" class="conditional-panel" style="display: none;">
<div id="domain-interagency-initaitive-details-container" class="conditional-panel">
<p class="usa-label">
Provide details below <span class="usa-label--required">*</span>
<em>Provide details below <span class="usa-label--required">*</span></em>
</p>
{% with add_label_class="usa-sr-only" attr_required="required" maxlength="2000" %}
{% input_with_errors forms.5.interagency_initiative_details %}
{% endwith %}
<p class="usa-hint">Maximum 2000 characters allowed.</p>
<p class="usa-hint margin-top-0">Maximum 2000 characters allowed.</p>
</div>
</fieldset>
{% else %}

View file

@ -745,26 +745,35 @@ class Purpose(DomainRequestWizard):
feb_initiative_details_form = forms_list[5]
if not self.requires_feb_questions():
# if FEB questions don't apply, mark all other forms for deletion
# if FEB questions don't apply, mark those forms for deletion
feb_purpose_options_form.mark_form_for_deletion()
feb_timeframe_yes_no_form.mark_form_for_deletion()
feb_timeframe_details_form.mark_form_for_deletion()
feb_initiative_yes_no_form.mark_form_for_deletion()
feb_initiative_details_form.mark_form_for_deletion()
# we only care about the purpose form in this case since it's used in both instances
# we only care about the purpose details form in this case since it's used in both instances
return purpose_details_form.is_valid()
if not feb_purpose_options_form.is_valid():
# Ensure details form doesn't throw errors if it's not showing
purpose_details_form.mark_form_for_deletion()
feb_timeframe_valid = feb_timeframe_yes_no_form.is_valid()
feb_initiative_valid = feb_initiative_yes_no_form.is_valid()
logger.debug(f"feb timeframe yesno: {feb_timeframe_yes_no_form.cleaned_data.get('has_timeframe')}")
logger.debug(f"FEB initiative yesno: {feb_initiative_yes_no_form.cleaned_data.get('is_interagency_initiative')}")
if not feb_initiative_yes_no_form.is_valid() or not feb_timeframe_yes_no_form.cleaned_data.get("has_timeframe"):
if not feb_timeframe_valid or not feb_timeframe_yes_no_form.cleaned_data.get("has_timeframe"):
# Ensure details form doesn't throw errors if it's not showing
feb_timeframe_details_form.mark_form_for_deletion()
if not feb_initiative_valid or not feb_initiative_yes_no_form.cleaned_data.get("is_interagency_initiative"):
# Ensure details form doesn't throw errors if it's not showing
feb_initiative_details_form.mark_form_for_deletion()
if not feb_timeframe_yes_no_form.is_valid() or not feb_initiative_yes_no_form.cleaned_data.get("is_interagency_initiative"):
# Ensure details form doesn't throw errors if it's not showing
feb_timeframe_details_form.mark_form_for_deletion()
for i, form in enumerate(forms_list):
logger.debug(f"Form {i} is marked for deletion: {form.form_data_marked_for_deletion}")
valid = all(form.is_valid() for form in forms_list if not form.form_data_marked_for_deletion)