Skip to content

Commit

Permalink
Feat(eligibility/form): custom validation message for index and confi…
Browse files Browse the repository at this point in the history
…rm fields (#2045)
  • Loading branch information
angela-tran authored Apr 25, 2024
2 parents b5bfd7f + ccff754 commit dd3bd7a
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 22 deletions.
24 changes: 23 additions & 1 deletion benefits/core/templates/core/includes/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,29 @@
$("#{{ form.id }}").on("submit", function(e) {
$(this).trigger("submitting");
});
});

{% if form.use_custom_validity %}
const validate = function(input_element) {
input_element.setCustomValidity(""); // clearing message sets input_element.validity.customError back to false

const valid = input_element.checkValidity();
if (!valid) {
input_element.setCustomValidity(input_element.dataset.customValidity);
}
}

$("button[type=submit]", "#{{ form.id }}").on("click", function(e) {
// revalidate all fields
$("[data-custom-validity]").each(function() {
let input_element = $(this)[0];
if (input_element) {
validate(input_element);
}
});
});

{% endif %}
});
</script>

{% if request.recaptcha %}
Expand Down
24 changes: 17 additions & 7 deletions benefits/eligibility/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ def __init__(self, agency: models.TransitAgency, *args, **kwargs):
self.classes = "col-lg-8"
# second element is not used since we render the whole label using selection_label_template,
# therefore set to None
self.fields["verifier"].choices = [(v.id, None) for v in verifiers]
self.fields["verifier"].widget.selection_label_templates = {v.id: v.selection_label_template for v in verifiers}
verifier_field = self.fields["verifier"]
verifier_field.choices = [(v.id, None) for v in verifiers]
verifier_field.widget.selection_label_templates = {v.id: v.selection_label_template for v in verifiers}
verifier_field.widget.attrs.update({"data-custom-validity": _("Please choose a transit benefit.")})
self.use_custom_validity = True

def clean(self):
if not recaptcha.verify(self.data):
Expand All @@ -48,11 +51,6 @@ class EligibilityVerificationForm(forms.Form):
submit_value = _("Find my record")
submitting_value = _("Checking")

_error_messages = {
"invalid": _("Check your input. The format looks wrong."),
"missing": _("This field is required."),
}

def __init__(
self,
title,
Expand All @@ -68,6 +66,8 @@ def __init__(
sub_input_mode=None,
sub_max_length=None,
sub_pattern=None,
sub_custom_validity=None,
name_custom_validity=None,
*args,
**kwargs,
):
Expand Down Expand Up @@ -117,6 +117,9 @@ def __init__(
sub_widget.attrs.update({"inputmode": sub_input_mode})
if sub_max_length:
sub_widget.attrs.update({"maxlength": sub_max_length})
if sub_custom_validity:
sub_widget.attrs.update({"data-custom-validity": sub_custom_validity})
self.use_custom_validity = True

self.fields["sub"] = forms.CharField(
label=sub_label,
Expand All @@ -127,6 +130,9 @@ def __init__(
name_widget = widgets.FormControlTextInput(placeholder=name_placeholder)
if name_max_length:
name_widget.attrs.update({"maxlength": name_max_length})
if name_custom_validity:
name_widget.attrs.update({"data-custom-validity": name_custom_validity})
self.use_custom_validity = True

self.fields["name"] = forms.CharField(label=name_label, widget=name_widget, help_text=name_help_text)

Expand Down Expand Up @@ -157,6 +163,8 @@ def __init__(self, *args, **kwargs):
sub_input_mode="numeric",
sub_max_length=5,
sub_pattern=r"\d{5}",
sub_custom_validity=_("Please enter a 5-digit number."),
name_custom_validity=_("Please enter your last name."),
*args,
**kwargs,
)
Expand Down Expand Up @@ -185,6 +193,8 @@ def __init__(self, *args, **kwargs):
sub_input_mode="numeric",
sub_max_length=4,
sub_pattern=r"\d{4}",
sub_custom_validity=_("Please enter a 4-digit number."),
name_custom_validity=_("Please enter your last name."),
*args,
**kwargs,
)
20 changes: 13 additions & 7 deletions benefits/locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: https://github.com/cal-itp/benefits/issues \n"
"POT-Creation-Date: 2024-04-22 12:32-0700\n"
"POT-Creation-Date: 2024-04-25 12:29-0700\n"
"Language: English\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
Expand Down Expand Up @@ -303,16 +303,13 @@ msgstr ""
msgid "Choose this benefit"
msgstr ""

msgid "Find my record"
msgstr ""

msgid "Checking"
msgid "Please choose a transit benefit."
msgstr ""

msgid "Check your input. The format looks wrong."
msgid "Find my record"
msgstr ""

msgid "This field is required."
msgid "Checking"
msgstr ""

msgid "Agency card information"
Expand Down Expand Up @@ -340,6 +337,12 @@ msgstr ""
msgid "This is a 5-digit number on the front and back of your card."
msgstr ""

msgid "Please enter a 5-digit number."
msgstr ""

msgid "Please enter your last name."
msgstr ""

msgid ""
"We use the information on your SBMTD Reduced Fare Mobility ID card to find "
"the record of your transit benefit in our system."
Expand All @@ -351,6 +354,9 @@ msgstr ""
msgid "This is a 4-digit number on the back of your card."
msgstr ""

msgid "Please enter a 4-digit number."
msgstr ""

msgid "Your contactless card details"
msgstr ""

Expand Down
20 changes: 13 additions & 7 deletions benefits/locale/es/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: https://github.com/cal-itp/benefits/issues \n"
"POT-Creation-Date: 2024-04-22 12:32-0700\n"
"POT-Creation-Date: 2024-04-25 12:29-0700\n"
"Language: Español\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
Expand Down Expand Up @@ -390,18 +390,15 @@ msgstr "¿A qué beneficio de tránsito le gustaría inscribirse?"
msgid "Choose this benefit"
msgstr "Elegir este beneficio"

msgid "Please choose a transit benefit."
msgstr ""

msgid "Find my record"
msgstr "Comprobar elegibilidad"

msgid "Checking"
msgstr "Comprobando"

msgid "Check your input. The format looks wrong."
msgstr "Verifique su entrada. El formato parece incorrecto."

msgid "This field is required."
msgstr "Este campo es requerido."

msgid "Agency card information"
msgstr "Información de la tarjeta de agencia"

Expand All @@ -427,6 +424,12 @@ msgstr "Número de tarjeta de cortesía de MST"
msgid "This is a 5-digit number on the front and back of your card."
msgstr "Este es un número de 5 dígitos en el anverso y reverso de su tarjeta."

msgid "Please enter a 5-digit number."
msgstr ""

msgid "Please enter your last name."
msgstr ""

msgid ""
"We use the information on your SBMTD Reduced Fare Mobility ID card to find "
"the record of your transit benefit in our system."
Expand All @@ -438,6 +441,9 @@ msgstr "Número de SBMTD Reduced Fare Mobility ID"
msgid "This is a 4-digit number on the back of your card."
msgstr "Este es un número de 4 dígitos en el reverso de su tarjeta."

msgid "Please enter a 4-digit number."
msgstr ""

msgid "Your contactless card details"
msgstr "Los datos de su tarjeta sin contacto"

Expand Down
37 changes: 37 additions & 0 deletions tests/pytest/eligibility/test_forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from benefits.eligibility.forms import MSTCourtesyCard, SBMTDMobilityPass


def test_MSTCourtesyCard():
form = MSTCourtesyCard(data={"sub": "12345", "name": "Gonzalez"})

assert form.is_valid()

sub_attrs = form.fields["sub"].widget.attrs
assert sub_attrs["pattern"] == r"\d{5}"
assert sub_attrs["inputmode"] == "numeric"
assert sub_attrs["maxlength"] == 5
assert sub_attrs["data-custom-validity"] == "Please enter a 5-digit number."

name_attrs = form.fields["name"].widget.attrs
assert name_attrs["maxlength"] == 255
assert name_attrs["data-custom-validity"] == "Please enter your last name."

assert form.use_custom_validity


def test_SBMTDMobilityPass():
form = SBMTDMobilityPass(data={"sub": "1234", "name": "Barbara"})

assert form.is_valid()

sub_attrs = form.fields["sub"].widget.attrs
assert sub_attrs["pattern"] == r"\d{4}"
assert sub_attrs["maxlength"] == 4
assert sub_attrs["inputmode"] == "numeric"
assert sub_attrs["data-custom-validity"] == "Please enter a 4-digit number."

name_attrs = form.fields["name"].widget.attrs
assert name_attrs["maxlength"] == 255
assert name_attrs["data-custom-validity"] == "Please enter your last name."

assert form.use_custom_validity

0 comments on commit dd3bd7a

Please sign in to comment.