Skip to content

Commit

Permalink
Refs #32338 -- Removed 'for ="..."' from RadioSelect's <label>.
Browse files Browse the repository at this point in the history
This improves accessibility for screen reader users.

Co-authored-by: Thibaud Colas <[email protected]>
  • Loading branch information
2 people authored and felixxm committed Jun 22, 2021
1 parent 4f0a034 commit b9e872b
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 18 deletions.
21 changes: 11 additions & 10 deletions django/forms/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -762,8 +762,18 @@ class RadioSelect(ChoiceWidget):
template_name = 'django/forms/widgets/radio.html'
option_template_name = 'django/forms/widgets/radio_option.html'

def id_for_label(self, id_, index=None):
"""
Don't include for="field_0" in <label> to improve accessibility when
using a screen reader, in addition clicking such a label would toggle
the first input.
"""
if index is None:
return ''
return super().id_for_label(id_, index)


class CheckboxSelectMultiple(ChoiceWidget):
class CheckboxSelectMultiple(RadioSelect):
allow_multiple_selected = True
input_type = 'checkbox'
template_name = 'django/forms/widgets/checkbox_select.html'
Expand All @@ -779,15 +789,6 @@ def value_omitted_from_data(self, data, files, name):
# never known if the value is actually omitted.
return False

def id_for_label(self, id_, index=None):
"""
Don't include for="field_0" in <label> because clicking such a label
would toggle the first checkbox.
"""
if index is None:
return ''
return super().id_for_label(id_, index)


class MultiWidget(Widget):
"""
Expand Down
13 changes: 7 additions & 6 deletions tests/forms_tests/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -613,13 +613,14 @@ class FrameworkForm(Form):
</ul>"""
)

# When RadioSelect is used with auto_id, and the whole form is printed using
# either as_table() or as_ul(), the label for the RadioSelect will point to the
# ID of the *first* radio button.
# When RadioSelect is used with auto_id, and the whole form is printed
# using either as_table() or as_ul(), the label for the RadioSelect
# will **not** point to the ID of the *first* radio button to improve
# accessibility for screen reader users.
self.assertHTMLEqual(
f.as_table(),
"""<tr><th><label for="id_name">Name:</label></th><td><input type="text" name="name" id="id_name" required></td></tr>
<tr><th><label for="id_language_0">Language:</label></th><td><ul id="id_language">
<tr><th><label>Language:</label></th><td><ul id="id_language">
<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" required>
Python</label></li>
<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" required>
Expand All @@ -629,7 +630,7 @@ class FrameworkForm(Form):
self.assertHTMLEqual(
f.as_ul(),
"""<li><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" required></li>
<li><label for="id_language_0">Language:</label> <ul id="id_language">
<li><label>Language:</label> <ul id="id_language">
<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" required>
Python</label></li>
<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" required>
Expand All @@ -639,7 +640,7 @@ class FrameworkForm(Form):
self.assertHTMLEqual(
f.as_p(),
"""<p><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" required></p>
<p><label for="id_language_0">Language:</label> <ul id="id_language">
<p><label>Language:</label> <ul id="id_language">
<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" required>
Python</label></li>
<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" required>
Expand Down
4 changes: 2 additions & 2 deletions tests/forms_tests/tests/test_i18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class SomeForm(Form):
f = SomeForm()
self.assertHTMLEqual(
f.as_p(),
'<p><label for="id_somechoice_0">\xc5\xf8\xdf:</label>'
'<p><label>\xc5\xf8\xdf:</label>'
'<ul id="id_somechoice">\n'
'<li><label for="id_somechoice_0">'
'<input type="radio" id="id_somechoice_0" value="\xc5" name="somechoice" required> '
Expand All @@ -76,7 +76,7 @@ class SomeForm(Form):
'<ul class="errorlist"><li>'
'\u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c'
'\u043d\u043e\u0435 \u043f\u043e\u043b\u0435.</li></ul>\n'
'<p><label for="id_somechoice_0">\xc5\xf8\xdf:</label>'
'<p><label>\xc5\xf8\xdf:</label>'
' <ul id="id_somechoice">\n<li><label for="id_somechoice_0">'
'<input type="radio" id="id_somechoice_0" value="\xc5" name="somechoice" required> '
'En tied\xe4</label></li>\n'
Expand Down

0 comments on commit b9e872b

Please sign in to comment.