mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-07 07:28:24 -04:00
fixed validation for radio and text input fields
This commit is contained in:
@@ -7,13 +7,17 @@ function showError(input, errorElement, message) {
|
|||||||
errorElement.textContent = message;
|
errorElement.textContent = message;
|
||||||
}, 10);
|
}, 10);
|
||||||
|
|
||||||
input.classList.add("usa-input--error");
|
if (input.type !== "radio" && input.type !== "checkbox") {
|
||||||
|
input.classList.add("usa-input--error");
|
||||||
|
}
|
||||||
input.setAttribute("aria-describedby", errorElement.id);
|
input.setAttribute("aria-describedby", errorElement.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideError(input, errorElement) {
|
function hideError(input, errorElement) {
|
||||||
errorElement.style.display = "none";
|
errorElement.style.display = "none";
|
||||||
input.classList.remove("usa-input--error");
|
if (input.type !== "radio" && input.type !== "checkbox") {
|
||||||
|
input.classList.remove("usa-input--error");
|
||||||
|
}
|
||||||
input.removeAttribute("aria-describedby");
|
input.removeAttribute("aria-describedby");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,13 +28,14 @@ function getFieldLabel(input) {
|
|||||||
|
|
||||||
// Attach validation logic to forms
|
// Attach validation logic to forms
|
||||||
function attachValidation() {
|
function attachValidation() {
|
||||||
const forms = document.querySelectorAll("form.send-one-off-form");
|
const forms = document.querySelectorAll('form[data-force-focus="True"]');
|
||||||
forms.forEach((form) => {
|
forms.forEach((form) => {
|
||||||
const inputs = form.querySelectorAll("input, textarea, select");
|
const inputs = form.querySelectorAll("input, textarea, select");
|
||||||
|
|
||||||
form.addEventListener("submit", function (event) {
|
form.addEventListener("submit", function (event) {
|
||||||
let isValid = true;
|
let isValid = true;
|
||||||
let firstInvalidInput = null;
|
let firstInvalidInput = null;
|
||||||
|
const validatedRadioNames = new Set();
|
||||||
|
|
||||||
inputs.forEach((input) => {
|
inputs.forEach((input) => {
|
||||||
const errorId = input.id ? `${input.id}-error` : `${input.name}-error`;
|
const errorId = input.id ? `${input.id}-error` : `${input.name}-error`;
|
||||||
@@ -41,16 +46,25 @@ function attachValidation() {
|
|||||||
errorElement.id = errorId;
|
errorElement.id = errorId;
|
||||||
errorElement.classList.add("usa-error-message");
|
errorElement.classList.add("usa-error-message");
|
||||||
errorElement.setAttribute("aria-live", "polite");
|
errorElement.setAttribute("aria-live", "polite");
|
||||||
input.insertAdjacentElement("afterend", errorElement);
|
if (input.type === "radio") {
|
||||||
}
|
const group = form.querySelectorAll(`input[name="${input.name}"]`);
|
||||||
|
const lastRadio = group[group.length - 1];
|
||||||
|
lastRadio.parentElement.insertAdjacentElement("afterend", errorElement);
|
||||||
|
} else {
|
||||||
|
input.insertAdjacentElement("afterend", errorElement);
|
||||||
|
} }
|
||||||
|
|
||||||
if (input.type === "radio") {
|
if (input.type === "radio") {
|
||||||
|
if (validatedRadioNames.has(input.name)) {
|
||||||
|
return; // already validated this group
|
||||||
|
}
|
||||||
|
validatedRadioNames.add(input.name);
|
||||||
// Find all radio buttons with the same name
|
// Find all radio buttons with the same name
|
||||||
const radioGroup = document.querySelectorAll(`input[name="${input.name}"]`);
|
const radioGroup = document.querySelectorAll(`input[name="${input.name}"]`);
|
||||||
const isChecked = Array.from(radioGroup).some(radio => radio.checked);
|
const isChecked = Array.from(radioGroup).some(radio => radio.checked);
|
||||||
|
|
||||||
if (!isChecked) {
|
if (!isChecked) {
|
||||||
showError(input, errorElement, `Error: ${getFieldLabel(input)} must be selected.`);
|
showError(input, errorElement, `Error: A selection must be made.`);
|
||||||
isValid = false;
|
isValid = false;
|
||||||
if (!firstInvalidInput) {
|
if (!firstInvalidInput) {
|
||||||
firstInvalidInput = input;
|
firstInvalidInput = input;
|
||||||
@@ -73,11 +87,21 @@ function attachValidation() {
|
|||||||
|
|
||||||
inputs.forEach((input) => {
|
inputs.forEach((input) => {
|
||||||
input.addEventListener("input", function () {
|
input.addEventListener("input", function () {
|
||||||
const errorElement = document.getElementById(`${input.id}-error`);
|
const errorElement = document.getElementById(input.id ? `${input.id}-error` : `${input.name}-error`);
|
||||||
if (input.value.trim() !== "" && errorElement) {
|
if (errorElement && input.value.trim() !== "") {
|
||||||
hideError(input, errorElement);
|
hideError(input, errorElement);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (input.type === "radio") {
|
||||||
|
input.addEventListener("change", function () {
|
||||||
|
console.log(`Radio ${input.id} changed`);
|
||||||
|
|
||||||
|
const groupError = document.getElementById(`${input.name}-error`)
|
||||||
|
|| document.getElementById(`${input.id}-error`);
|
||||||
|
if (groupError) hideError(input, groupError);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -781,6 +781,9 @@ def govuk_radios_field_widget(self, field, param_extensions=None, **kwargs):
|
|||||||
# returns either a list or a hierarchy of lists
|
# returns either a list or a hierarchy of lists
|
||||||
# depending on how get_items_from_options is implemented
|
# depending on how get_items_from_options is implemented
|
||||||
items = self.get_items_from_options(field)
|
items = self.get_items_from_options(field)
|
||||||
|
is_field_required = False
|
||||||
|
if getattr(field, 'flags', None) and 'required' in field.flags:
|
||||||
|
is_field_required = True
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
"name": field.name,
|
"name": field.name,
|
||||||
@@ -793,6 +796,8 @@ def govuk_radios_field_widget(self, field, param_extensions=None, **kwargs):
|
|||||||
},
|
},
|
||||||
"errorMessage": error_message,
|
"errorMessage": error_message,
|
||||||
"items": items,
|
"items": items,
|
||||||
|
"required": is_field_required,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# extend default params with any sent in during instantiation
|
# extend default params with any sent in during instantiation
|
||||||
|
|||||||
@@ -56,7 +56,6 @@
|
|||||||
{% set itemHintId = id + '-item-hint' %}
|
{% set itemHintId = id + '-item-hint' %}
|
||||||
<div class="usa-radio">
|
<div class="usa-radio">
|
||||||
<input class="usa-radio__input" id="{{ id }}" name="{{ params.name }}" type="radio" value="{{ item.value }}"
|
<input class="usa-radio__input" id="{{ id }}" name="{{ params.name }}" type="radio" value="{{ item.value }}"
|
||||||
{{-" checked" if item.checked }}
|
|
||||||
{{-" disabled" if item.disabled }}
|
{{-" disabled" if item.disabled }}
|
||||||
{%- if item.conditional %} data-aria-controls="{{ conditionalId }}"{% endif -%}
|
{%- if item.conditional %} data-aria-controls="{{ conditionalId }}"{% endif -%}
|
||||||
{%- if hasHint %} aria-describedby="{{ itemHintId }}"{% endif -%}
|
{%- if hasHint %} aria-describedby="{{ itemHintId }}"{% endif -%}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
class=None,
|
class=None,
|
||||||
id=None,
|
id=None,
|
||||||
module=None,
|
module=None,
|
||||||
data_kwargs={}
|
data_kwargs={},
|
||||||
|
data_force_focus=False
|
||||||
) %}
|
) %}
|
||||||
<form
|
<form
|
||||||
method="{{ method }}"
|
method="{{ method }}"
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
data-{{ key }}="{{ val }}"
|
data-{{ key }}="{{ val }}"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% if data_force_focus %}data-force-focus="{{ data_force_focus }}"{% endif %}
|
||||||
novalidate
|
novalidate
|
||||||
>
|
>
|
||||||
{{ caller() }}
|
{{ caller() }}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
{{ page_header('About your service') }}
|
{{ page_header('About your service') }}
|
||||||
|
|
||||||
{% call form_wrapper() %}
|
{% call form_wrapper(data_force_focus=True) %}
|
||||||
|
|
||||||
{{ form.name(param_extensions={"hint": {"text": "You can change this later"}}) }}
|
{{ form.name(param_extensions={"hint": {"text": "You can change this later"}}) }}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
{% set content_hint = 'Your service name will be added to the start of your message. You can turn this off in Settings.' %}
|
{% set content_hint = 'Your service name will be added to the start of your message. You can turn this off in Settings.' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% call form_wrapper() %}
|
{% call form_wrapper(data_force_focus=True) %}
|
||||||
<div class="grid-container padding-0">
|
<div class="grid-container padding-0">
|
||||||
<div class="tablet:grid-col-9 mobile-lg:grid-col-12">
|
<div class="tablet:grid-col-9 mobile-lg:grid-col-12">
|
||||||
{{ form.name(param_extensions={
|
{{ form.name(param_extensions={
|
||||||
|
|||||||
@@ -34,7 +34,8 @@
|
|||||||
{% call form_wrapper(
|
{% call form_wrapper(
|
||||||
class='js-stick-at-top-when-scrolling send-one-off-form' if template.template_type != 'sms' else 'send-one-off-form',
|
class='js-stick-at-top-when-scrolling send-one-off-form' if template.template_type != 'sms' else 'send-one-off-form',
|
||||||
module="autofocus",
|
module="autofocus",
|
||||||
data_kwargs={'force-focus': True}
|
data_kwargs={'force-focus': True},
|
||||||
|
data_force_focus=True
|
||||||
) %}
|
) %}
|
||||||
<div class="grid-row">
|
<div class="grid-row">
|
||||||
{% set extra_class = "extra-tracking" if form.placeholder_value.label.text == "phone number" else "" %}
|
{% set extra_class = "extra-tracking" if form.placeholder_value.label.text == "phone number" else "" %}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
label='Search by name',
|
label='Search by name',
|
||||||
autofocus=True
|
autofocus=True
|
||||||
) }}
|
) }}
|
||||||
{% call form_wrapper() %}
|
{% call form_wrapper(data_force_focus=True) %}
|
||||||
{% if has_organizations %}
|
{% if has_organizations %}
|
||||||
{{ form.organizations }}
|
{{ form.organizations }}
|
||||||
{{ sticky_page_footer('Save') }}
|
{{ sticky_page_footer('Save') }}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
See <a class="usa-link" href="{{ url_for(".pricing") }}">pricing</a> for the list
|
See <a class="usa-link" href="{{ url_for(".pricing") }}">pricing</a> for the list
|
||||||
of rates.
|
of rates.
|
||||||
</p>
|
</p>
|
||||||
{% call form_wrapper() %}
|
{% call form_wrapper(data_force_focus=True) %}
|
||||||
{{ form.enabled }}
|
{{ form.enabled }}
|
||||||
{{ page_footer('Save') }}
|
{{ page_footer('Save') }}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
|
|||||||
@@ -20,12 +20,7 @@
|
|||||||
<p>
|
<p>
|
||||||
You may send up to 250,000 text messages during the pilot period.
|
You may send up to 250,000 text messages during the pilot period.
|
||||||
</p>
|
</p>
|
||||||
<!--<p>
|
{% call form_wrapper(data_force_focus=True) %}
|
||||||
You have a free allowance of
|
|
||||||
{{ '{:,}'.format(current_service.free_sms_fragment_limit) }} text messages each
|
|
||||||
financial year.
|
|
||||||
</p>-->
|
|
||||||
{% call form_wrapper() %}
|
|
||||||
{{ form.enabled }}
|
{{ form.enabled }}
|
||||||
{{ page_footer('Save') }}
|
{{ page_footer('Save') }}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
{{ page_header('Start text messages with service name') }}
|
{{ page_header('Start text messages with service name') }}
|
||||||
|
|
||||||
{% call form_wrapper() %}
|
{% call form_wrapper(data_force_focus=True) %}
|
||||||
{{ form.enabled }}
|
{{ form.enabled }}
|
||||||
{{ page_footer('Save') }}
|
{{ page_footer('Save') }}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
{{ page_header('Add text message sender') }}
|
{{ page_header('Add text message sender') }}
|
||||||
|
|
||||||
{% call form_wrapper() %}
|
{% call form_wrapper(data_force_focus=True) %}
|
||||||
{{ form.sms_sender(param_extensions={
|
{{ form.sms_sender(param_extensions={
|
||||||
"hint": {"text": "Up to 11 characters, letters, numbers and spaces only"}
|
"hint": {"text": "Up to 11 characters, letters, numbers and spaces only"}
|
||||||
}) }}
|
}) }}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
{{ page_header('Change text message sender') }}
|
{{ page_header('Change text message sender') }}
|
||||||
{% call form_wrapper() %}
|
{% call form_wrapper(data_force_focus=True) %}
|
||||||
{% if inbound_number %}
|
{% if inbound_number %}
|
||||||
<p>
|
<p>
|
||||||
<span class="bottom-gutter-1-3"> {{ sms_sender.sms_sender }} </span>
|
<span class="bottom-gutter-1-3"> {{ sms_sender.sms_sender }} </span>
|
||||||
|
|||||||
Reference in New Issue
Block a user