mirror of
https://github.com/django/django.git
synced 2024-12-22 09:05:43 +00:00
Refs #32819 -- Added aria-describedby property to BoundField.
This commit is contained in:
parent
27375ad50e
commit
1e05431881
@ -289,20 +289,24 @@ class BoundField(RenderableFieldMixin):
|
|||||||
attrs["disabled"] = True
|
attrs["disabled"] = True
|
||||||
if not widget.is_hidden and self.errors:
|
if not widget.is_hidden and self.errors:
|
||||||
attrs["aria-invalid"] = "true"
|
attrs["aria-invalid"] = "true"
|
||||||
# If a custom aria-describedby attribute is given (either via the attrs
|
# Preserve aria-describedby provided by the attrs argument so user
|
||||||
# argument or widget.attrs) and help_text is used, the custom
|
# can set the desired order.
|
||||||
# aria-described by is preserved so user can set the desired order.
|
if not attrs.get("aria-describedby") and not self.use_fieldset:
|
||||||
if (
|
if aria_describedby := self.aria_describedby:
|
||||||
not attrs.get("aria-describedby")
|
attrs["aria-describedby"] = aria_describedby
|
||||||
and not widget.attrs.get("aria-describedby")
|
|
||||||
and self.field.help_text
|
|
||||||
and not self.use_fieldset
|
|
||||||
and self.auto_id
|
|
||||||
and not self.is_hidden
|
|
||||||
):
|
|
||||||
attrs["aria-describedby"] = f"{self.auto_id}_helptext"
|
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
|
@property
|
||||||
|
def aria_describedby(self):
|
||||||
|
# Preserve aria-describedby set on the widget.
|
||||||
|
if self.field.widget.attrs.get("aria-describedby"):
|
||||||
|
return None
|
||||||
|
aria_describedby = []
|
||||||
|
if self.auto_id and not self.is_hidden:
|
||||||
|
if self.help_text:
|
||||||
|
aria_describedby.append(f"{self.auto_id}_helptext")
|
||||||
|
return " ".join(aria_describedby)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def widget_type(self):
|
def widget_type(self):
|
||||||
return re.sub(
|
return re.sub(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{% if field.use_fieldset %}
|
{% if field.use_fieldset %}
|
||||||
<fieldset{% if field.help_text and field.auto_id and "aria-describedby" not in field.field.widget.attrs %} aria-describedby="{{ field.auto_id }}_helptext"{% endif %}>
|
<fieldset{% if field.aria_describedby %} aria-describedby="{{ field.aria_describedby }}"{% endif %}>
|
||||||
{% if field.label %}{{ field.legend_tag() }}{% endif %}
|
{% if field.label %}{{ field.legend_tag() }}{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if field.label %}{{ field.label_tag() }}{% endif %}
|
{% if field.label %}{{ field.label_tag() }}{% endif %}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{% if field.use_fieldset %}
|
{% if field.use_fieldset %}
|
||||||
<fieldset{% if field.help_text and field.auto_id and "aria-describedby" not in field.field.widget.attrs %} aria-describedby="{{ field.auto_id }}_helptext"{% endif %}>
|
<fieldset{% if field.aria_describedby %} aria-describedby="{{ field.aria_describedby }}"{% endif %}>
|
||||||
{% if field.label %}{{ field.legend_tag }}{% endif %}
|
{% if field.label %}{{ field.legend_tag }}{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if field.label %}{{ field.label_tag }}{% endif %}
|
{% if field.label %}{{ field.label_tag }}{% endif %}
|
||||||
|
@ -1161,6 +1161,15 @@ The field-specific output honors the form object's ``auto_id`` setting:
|
|||||||
Attributes of ``BoundField``
|
Attributes of ``BoundField``
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
.. attribute:: BoundField.aria_describedby
|
||||||
|
|
||||||
|
.. versionadded:: 5.2
|
||||||
|
|
||||||
|
Returns an ``aria-describedby`` reference to associate a field with its
|
||||||
|
help text. Returns ``None`` if ``aria-describedby`` is set in
|
||||||
|
:attr:`Widget.attrs` to preserve the user defined attribute when rendering
|
||||||
|
the form.
|
||||||
|
|
||||||
.. attribute:: BoundField.auto_id
|
.. attribute:: BoundField.auto_id
|
||||||
|
|
||||||
The HTML ID attribute for this ``BoundField``. Returns an empty string
|
The HTML ID attribute for this ``BoundField``. Returns an empty string
|
||||||
|
@ -256,6 +256,9 @@ Forms
|
|||||||
HTML ``id`` attribute to be added in the error template. See
|
HTML ``id`` attribute to be added in the error template. See
|
||||||
:attr:`.ErrorList.field_id` for details.
|
:attr:`.ErrorList.field_id` for details.
|
||||||
|
|
||||||
|
* An :attr:`~django.forms.BoundField.aria_describedby` property is added to
|
||||||
|
``BoundField`` to ease use of this HTML attribute in templates.
|
||||||
|
|
||||||
Generic Views
|
Generic Views
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -4801,6 +4801,34 @@ Options: <select multiple name="options" aria-invalid="true" required>
|
|||||||
with self.assertRaises(KeyError):
|
with self.assertRaises(KeyError):
|
||||||
f["name"]
|
f["name"]
|
||||||
|
|
||||||
|
def test_aria_describedby_property(self):
|
||||||
|
class TestForm(Form):
|
||||||
|
name = CharField(help_text="Some help text")
|
||||||
|
|
||||||
|
form = TestForm({"name": "MyName"})
|
||||||
|
self.assertEqual(form["name"].aria_describedby, "id_name_helptext")
|
||||||
|
|
||||||
|
form = TestForm(auto_id=None)
|
||||||
|
self.assertEqual(form["name"].aria_describedby, "")
|
||||||
|
|
||||||
|
class TestFormHidden(Form):
|
||||||
|
name = CharField(help_text="Some help text", widget=HiddenInput)
|
||||||
|
|
||||||
|
form = TestFormHidden()
|
||||||
|
self.assertEqual(form["name"].aria_describedby, "")
|
||||||
|
|
||||||
|
class TestFormWithAttrs(Form):
|
||||||
|
name = CharField(widget=TextInput(attrs={"aria-describedby": "my-id"}))
|
||||||
|
|
||||||
|
form = TestFormWithAttrs({"name": "MyName"})
|
||||||
|
self.assertIs(form["name"].aria_describedby, None)
|
||||||
|
|
||||||
|
class TestFormWithoutHelpText(Form):
|
||||||
|
name = CharField()
|
||||||
|
|
||||||
|
form = TestFormWithoutHelpText()
|
||||||
|
self.assertEqual(form["name"].aria_describedby, "")
|
||||||
|
|
||||||
|
|
||||||
@jinja2_tests
|
@jinja2_tests
|
||||||
class Jinja2FormsTestCase(FormsTestCase):
|
class Jinja2FormsTestCase(FormsTestCase):
|
||||||
|
Loading…
Reference in New Issue
Block a user