Skip to content

Commit

Permalink
Improve error handling in forms (#52)
Browse files Browse the repository at this point in the history
* Update dependencies

* Create Makefile

* Add error handling

* Improved error handling in forms

* Update test
  • Loading branch information
Ash-Crow authored Jul 6, 2023
1 parent d2a965f commit 702ae22
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 186 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
runserver:
poetry run python manage.py runserver 8765
7 changes: 7 additions & 0 deletions dsfr/templates/dsfr/form_field_snippets/checkbox_snippet.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
{% load widget_tweaks %}
<div class="fr-checkbox-group{% if field.errors %} fr-checkbox-group--error{% endif %}{% if field.field.disabled %} fr-input-group--disabled{% endif %}">
{% if field.errors %}
{% with aria_describedby="aria-describedby:"|add:field.auto_id|add:"-desc-error" %}
{{ field|attr:aria_describedby }}
{% endwith %}
{% else %}
{{ field }}
{% endif %}

{{ field.label_tag }}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
{% load widget_tweaks %}
<div class="fr-form-group{% if field.errors %} fr-form-group--error{% endif %}{% if field.field.disabled %} fr-form-group--disabled{% endif %}">
<fieldset class="fr-fieldset">
<legend class="fr-fieldset__legend fr-text--regular" id="checkboxes-legend-{{ field.auto_id }}">
{{ field.label_tag }}{% if field.field.required %} *{% endif %}
{% if field.help_text %}<span class="fr-hint-text">{{ field.help_text }}</span>{% endif %}
</legend>
<fieldset class="fr-fieldset{% if field.errors %} fr-fieldset--error{% endif %}" id="checkboxes-{{ field.auto_id }}" aria-labelledby="{{ field.auto_id }}-legend{% if field.errors %} {{ field.auto_id }}-messages{% endif %}">
<legend class="fr-fieldset__legend fr-text--regular" id="{{ field.auto_id }}-legend">
{{ field.label_tag }}{% if field.field.required %} *{% endif %}
{% if field.help_text %}<span class="fr-hint-text">{{ field.help_text }}</span>{% endif %}
</legend>

<div class="fr-fieldset__content">
<div class="fr-fieldset__content">
{% if field.field.disabled %}
{{ field|attr:"disabled" }}
{% else %}
{{ field }}
</div>

{% if field.errors %}
<div id="{{ field.auto_id }}-desc-error" class="fr-error-text">
{{ field.errors }}
</div>
{% endif %}
</fieldset>
</div>
</div>

{% if field.errors %}
<div id="{{ field.auto_id }}-messages" class="fr-error-text">
{{ field.errors }}
</div>
{% endif %}
</fieldset>
8 changes: 4 additions & 4 deletions dsfr/templates/dsfr/form_field_snippets/input_snippet.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
{{ field.label_tag }}{% if field.field.required %} *{% endif %}
{% if field.help_text %}<span class="fr-hint-text">{{ field.help_text }}</span>{% endif %}

{% if field|widget_type == "dateinput" %}
<div class="fr-input-wrap fr-icon-calendar-line">
{{ field }}
</div>
{% if field.errors %}
{% with aria_describedby="aria-describedby:"|add:field.auto_id|add:"-desc-error" %}
{{ field|attr:"aria-invalid:true"|attr:aria_describedby }}
{% endwith %}
{% else %}
{{ field }}
{% endif %}
Expand Down
33 changes: 18 additions & 15 deletions dsfr/templates/dsfr/form_field_snippets/radioselect_snippet.html
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
{% load widget_tweaks %}
<div class="fr-form-group{% if field.errors %} fr-form-group--error{% endif %}{% if field.field.disabled %} fr-form-group--disabled{% endif %}">
<fieldset class="fr-fieldset">
<legend class="fr-fieldset__legend fr-text--regular" id="radio-legend-{{ field.auto_id }}">
{{ field.label_tag }}{% if field.field.required %} *{% endif %}
{% if field.help_text %}<span class="fr-hint-text">{{ field.help_text }}</span>{% endif %}
</legend>
<fieldset class="fr-fieldset{% if field.errors %} fr-fieldset--error{% endif %}" id="radio-{{ field.auto_id }}" aria-labelledby="{{ field.auto_id }}-legend{% if field.errors %} {{ field.auto_id }}-messages{% endif %}">
<legend class="fr-fieldset__legend fr-text--regular" id="{{ field.auto_id }}-legend">
{{ field.label_tag }}{% if field.field.required %} *{% endif %}
{% if field.help_text %}<span class="fr-hint-text">{{ field.help_text }}</span>{% endif %}
</legend>

<div class="fr-fieldset__content">
{{ field|add_class:"fr-radio-group" }}
</div>
<div class="fr-fieldset__content">
{% if field.field.disabled %}
{{ field|add_class:"fr-radio-group"|attr:"disabled" }}
{% else %}
{{ field|add_class:"fr-radio-group" }}
{% endif %}
</div>

{% if field.errors %}
<div id="{{ field.auto_id }}-desc-error" class="fr-error-text">
{% if field.errors %}
<div class="fr-messages-group fr-error-text" id="{{ field.auto_id }}-messages">
{{ field.errors }}
</div>
{% endif %}
</fieldset>
</div>
</div>
{% endif %}
</fieldset>

26 changes: 25 additions & 1 deletion example_app/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,19 @@ class ExampleForm(DsfrBaseForm):
label="Boutons radio",
required=False,
choices=[(1, "Premier choix"), (2, "Second choix"), (3, "Troisième choix")],
help_text="Le troisième choix renvoie une erreur s’il est sélectionné",
widget=forms.RadioSelect,
)

sample_checkbox = forms.ChoiceField(
label="Cases à cocher",
required=False,
choices=[(1, "Premier choix"), (2, "Second choix"), (3, "Troisième choix")],
choices=[
("1", "Premier choix"),
("2", "Second choix"),
("3", "Troisième choix"),
],
help_text="Le troisième choix renvoie une erreur s’il est sélectionné",
widget=forms.CheckboxSelectMultiple,
)

Expand All @@ -90,6 +96,24 @@ def clean_sample_number(self):
if sample_number < 0:
raise forms.ValidationError("Merci d’entrer un nombre positif")

return sample_number

def clean_sample_radio(self):
sample_radio = self.cleaned_data["sample_radio"]

if sample_radio == "3":
raise forms.ValidationError("Le troisième choix est interdit")

return sample_radio

def clean_sample_checkbox(self):
sample_checkbox = self.cleaned_data["sample_checkbox"]

if sample_checkbox == ["2"]:
raise forms.ValidationError("Le troisième choix est interdit")

return sample_checkbox

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_autofocus_on_first_error()
5 changes: 3 additions & 2 deletions example_app/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ def test_form_sets_autofocus_on_first_error(self):
self.assertEqual(response.status_code, HTTPStatus.OK)
self.assertContains(
response,
"""<input type="number" name="sample_number" value="-5"
class="fr-input" autofocus="" required id="id_sample_number">""",
"""<input type="number" name="sample_number" value="-5" class="fr-input"
autofocus="" aria-describedby="id_sample_number-desc-error" aria-invalid="true"
required id="id_sample_number">""",
html=True,
)
self.assertContains(response, "Merci d’entrer un nombre positif", html=True)
Loading

0 comments on commit 702ae22

Please sign in to comment.