Refs #32819 -- Used auto_id instead of id_for_label as unique identifier for the field.

`id_for_label` is blank for widgets with multiple inputs such as radios
and multiple checkboxes. Therefore , `help_text` for fields using these
widgets cannot currently be associated using `aria-describedby`.
`id_for_label` is being used as a guard to avoid incorrectly adding
`aria-describedby` to those widgets.

This change uses `auto_id` as the unique identified for the fields
`help_text`. A guard is added to avoid incorrectly adding
`aria-describedby` to inputs by checking the widget's `use_fieldset`
attribute. Fields rendered in a `<fieldset>` should have
`aria-describedby` added to the `<fieldset>` and not every `<input>`.
This commit is contained in:
David Smith 2023-11-15 20:51:00 +00:00 committed by Mariusz Felisiak
parent 61c305f298
commit 292f1ea90f
12 changed files with 18 additions and 17 deletions

View File

@ -296,9 +296,10 @@ class BoundField(RenderableFieldMixin):
not attrs.get("aria-describedby") not attrs.get("aria-describedby")
and not widget.attrs.get("aria-describedby") and not widget.attrs.get("aria-describedby")
and self.field.help_text and self.field.help_text
and self.id_for_label and not self.use_fieldset
and self.auto_id
): ):
attrs["aria-describedby"] = f"{self.id_for_label}_helptext" attrs["aria-describedby"] = f"{self.auto_id}_helptext"
return attrs return attrs
@property @property

View File

@ -4,7 +4,7 @@
{% else %} {% else %}
{% if field.label %}{{ field.label_tag() }}{% endif %} {% if field.label %}{{ field.label_tag() }}{% endif %}
{% endif %} {% endif %}
{% if field.help_text %}<div class="helptext"{% if field.id_for_label %} id="{{ field.id_for_label}}_helptext"{% endif %}>{{ field.help_text|safe }}</div>{% endif %} {% if field.help_text %}<div class="helptext"{% if field.auto_id %} id="{{ field.auto_id }}_helptext"{% endif %}>{{ field.help_text|safe }}</div>{% endif %}
{{ field.errors }} {{ field.errors }}
{{ field }} {{ field }}
{% if field.use_fieldset %}</fieldset>{% endif %} {% if field.use_fieldset %}</fieldset>{% endif %}

View File

@ -8,7 +8,7 @@
{% if field.label %}{{ field.label_tag() }}{% endif %} {% if field.label %}{{ field.label_tag() }}{% endif %}
{{ field }} {{ field }}
{% if field.help_text %} {% if field.help_text %}
<span class="helptext"{% if field.id_for_label %} id="{{ field.id_for_label}}_helptext"{% endif %}>{{ field.help_text|safe }}</span> <span class="helptext"{% if field.auto_id %} id="{{ field.auto_id }}_helptext"{% endif %}>{{ field.help_text|safe }}</span>
{% endif %} {% endif %}
{% if loop.last %} {% if loop.last %}
{% for field in hidden_fields %}{{ field }}{% endfor %} {% for field in hidden_fields %}{{ field }}{% endfor %}

View File

@ -16,7 +16,7 @@
{{ field }} {{ field }}
{% if field.help_text %} {% if field.help_text %}
<br> <br>
<span class="helptext"{% if field.id_for_label %} id="{{ field.id_for_label}}_helptext"{% endif %}>{{ field.help_text|safe }}</span> <span class="helptext"{% if field.auto_id %} id="{{ field.auto_id }}_helptext"{% endif %}>{{ field.help_text|safe }}</span>
{% endif %} {% endif %}
{% if loop.last %} {% if loop.last %}
{% for field in hidden_fields %}{{ field }}{% endfor %} {% for field in hidden_fields %}{{ field }}{% endfor %}

View File

@ -12,7 +12,7 @@
{% if field.label %}{{ field.label_tag() }}{% endif %} {% if field.label %}{{ field.label_tag() }}{% endif %}
{{ field }} {{ field }}
{% if field.help_text %} {% if field.help_text %}
<span class="helptext"{% if field.id_for_label %} id="{{ field.id_for_label}}_helptext"{% endif %}>{{ field.help_text|safe }}</span> <span class="helptext"{% if field.auto_id %} id="{{ field.auto_id }}_helptext"{% endif %}>{{ field.help_text|safe }}</span>
{% endif %} {% endif %}
{% if loop.last %} {% if loop.last %}
{% for field in hidden_fields %}{{ field }}{% endfor %} {% for field in hidden_fields %}{{ field }}{% endfor %}

View File

@ -4,7 +4,7 @@
{% else %} {% else %}
{% if field.label %}{{ field.label_tag }}{% endif %} {% if field.label %}{{ field.label_tag }}{% endif %}
{% endif %} {% endif %}
{% if field.help_text %}<div class="helptext"{% if field.id_for_label %} id="{{ field.id_for_label}}_helptext"{% endif %}>{{ field.help_text|safe }}</div>{% endif %} {% if field.help_text %}<div class="helptext"{% if field.auto_id %} id="{{ field.auto_id }}_helptext"{% endif %}>{{ field.help_text|safe }}</div>{% endif %}
{{ field.errors }} {{ field.errors }}
{{ field }} {{ field }}
{% if field.use_fieldset %}</fieldset>{% endif %} {% if field.use_fieldset %}</fieldset>{% endif %}

View File

@ -8,7 +8,7 @@
{% if field.label %}{{ field.label_tag }}{% endif %} {% if field.label %}{{ field.label_tag }}{% endif %}
{{ field }} {{ field }}
{% if field.help_text %} {% if field.help_text %}
<span class="helptext"{% if field.id_for_label %} id="{{ field.id_for_label}}_helptext"{% endif %}>{{ field.help_text|safe }}</span> <span class="helptext"{% if field.auto_id %} id="{{ field.auto_id }}_helptext"{% endif %}>{{ field.help_text|safe }}</span>
{% endif %} {% endif %}
{% if forloop.last %} {% if forloop.last %}
{% for field in hidden_fields %}{{ field }}{% endfor %} {% for field in hidden_fields %}{{ field }}{% endfor %}

View File

@ -16,7 +16,7 @@
{{ field }} {{ field }}
{% if field.help_text %} {% if field.help_text %}
<br> <br>
<span class="helptext"{% if field.id_for_label %} id="{{ field.id_for_label}}_helptext"{% endif %}>{{ field.help_text|safe }}</span> <span class="helptext"{% if field.auto_id %} id="{{ field.auto_id }}_helptext"{% endif %}>{{ field.help_text|safe }}</span>
{% endif %} {% endif %}
{% if forloop.last %} {% if forloop.last %}
{% for field in hidden_fields %}{{ field }}{% endfor %} {% for field in hidden_fields %}{{ field }}{% endfor %}

View File

@ -12,7 +12,7 @@
{% if field.label %}{{ field.label_tag }}{% endif %} {% if field.label %}{{ field.label_tag }}{% endif %}
{{ field }} {{ field }}
{% if field.help_text %} {% if field.help_text %}
<span class="helptext"{% if field.id_for_label %} id="{{ field.id_for_label}}_helptext"{% endif %}>{{ field.help_text|safe }}</span> <span class="helptext"{% if field.auto_id %} id="{{ field.auto_id }}_helptext"{% endif %}>{{ field.help_text|safe }}</span>
{% endif %} {% endif %}
{% if forloop.last %} {% if forloop.last %}
{% for field in hidden_fields %}{{ field }}{% endfor %} {% for field in hidden_fields %}{{ field }}{% endfor %}

View File

@ -283,9 +283,9 @@ fields. We've specified ``auto_id=False`` to simplify the output:
<div>Sender:<div class="helptext">A valid email address, please.</div><input type="email" name="sender" required></div> <div>Sender:<div class="helptext">A valid email address, please.</div><input type="email" name="sender" required></div>
<div>Cc myself:<input type="checkbox" name="cc_myself"></div> <div>Cc myself:<input type="checkbox" name="cc_myself"></div>
When a field has help text and :attr:`~django.forms.BoundField.id_for_label` When a field has help text and the widget is not rendered in a ``<fieldset>``,
returns a value, we associate ``help_text`` with the input using the ``aria-describedby`` is added to the ``<input>`` to associate it to the
``aria-describedby`` HTML attribute: help text:
.. code-block:: pycon .. code-block:: pycon

View File

@ -61,7 +61,7 @@ For example, the template below:
<div> <div>
{{ form.name.label_tag }} {{ form.name.label_tag }}
{% if form.name.help_text %} {% if form.name.help_text %}
<div class="helptext" id="{{ form.name.id_for_label }}_helptext"> <div class="helptext" id="{{ form.name.auto_id }}_helptext">
{{ form.name.help_text|safe }} {{ form.name.help_text|safe }}
</div> </div>
{% endif %} {% endif %}
@ -71,7 +71,7 @@ For example, the template below:
<div class="col"> <div class="col">
{{ form.email.label_tag }} {{ form.email.label_tag }}
{% if form.email.help_text %} {% if form.email.help_text %}
<div class="helptext" id="{{ form.email.id_for_label }}_helptext"> <div class="helptext" id="{{ form.email.auto_id }}_helptext">
{{ form.email.help_text|safe }} {{ form.email.help_text|safe }}
</div> </div>
{% endif %} {% endif %}
@ -81,7 +81,7 @@ For example, the template below:
<div class="col"> <div class="col">
{{ form.password.label_tag }} {{ form.password.label_tag }}
{% if form.password.help_text %} {% if form.password.help_text %}
<div class="helptext" id="{{ form.password.id_for_label }}_helptext"> <div class="helptext" id="{{ form.password.auto_id }}_helptext">
{{ form.password.help_text|safe }} {{ form.password.help_text|safe }}
</div> </div>
{% endif %} {% endif %}

View File

@ -723,7 +723,7 @@ loop:
{{ field.errors }} {{ field.errors }}
{{ field.label_tag }} {{ field }} {{ field.label_tag }} {{ field }}
{% if field.help_text %} {% if field.help_text %}
<p class="help" id="{{ field.id_for_label }}_helptext"> <p class="help" id="{{ field.auto_id }}_helptext">
{{ field.help_text|safe }} {{ field.help_text|safe }}
</p> </p>
{% endif %} {% endif %}