-
-
Notifications
You must be signed in to change notification settings - Fork 32.8k
Fixed #35892 -- Supported Widget.use_fieldset in admin forms and linked help texts aria-describedby for accessibility. #19678
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -47,7 +47,7 @@ Requires core.js and SelectBox.js. | |||
'p', | |||
selector_available_title, | |||
interpolate(gettext('Choose %s by selecting them and then select the "Choose" arrow button.'), [field_name]), | |||
'class', 'helptext' | |||
'id', `${field_id}_choose_helptext`, 'class', 'helptext' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the help text for the from box rather than the help text for the fieldset, so the from box should have the aria-describedby
attribute (not the fieldset). Similar for the to box
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for pointing out such an important detail.
Currently, when the select element is focused, it’s connected to the title via aria-labelledby
, so both the label and a description are provided.
However, it might be better to provide the label via aria-labelledby
, and then connect the help text and the instructions for selecting multiple options using aria-describedby
.
warning.classList.add('help', warningClass); | ||
warning.id = `${field_id}_timezone_warning_helptext`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this helptext should also be specific to the input rather than the fieldset
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think the same. It seems better to associate it with each input element.
@@ -282,6 +287,8 @@ def __init__( | |||
self.can_view_related = not multiple and can_view_related | |||
# To check if the related object is registered with this AdminSite. | |||
self.admin_site = admin_site | |||
self.use_fieldset = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We potentially need to add use_fieldset = True
to django.forms.widgets.ClearableFileInput
which also is used (slightly customized) in the admin
Maybe add in a separate commit prior to this one if you agree with a test for forms
55815b2
to
5b17a6e
Compare
New Accessibility Improvement Project 🎉🎉🎉 |
…ed help texts aria-describedby for accessibility.
9403679
to
93a290f
Compare
I also think it looks fine. More consistent with other labels 🤷 |
django/contrib/admin/templates/admin/widgets/split_datetime.html
Outdated
Show resolved
Hide resolved
93a290f
to
878b956
Compare
878b956
to
8289d96
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that the legends are styled black (rather than the grey styling of the labels), which needs an update
I did some testing with a screen reader and this is definitely an improvement to what we had 😁
I think this is getting close but I will let the accessibility team do more in depth testing
@@ -437,9 +441,14 @@ def test_render(self): | |||
self.assertHTMLEqual( | |||
w.render("test", datetime(2007, 12, 1, 9, 30)), | |||
'<p class="datetime">' | |||
'Date: <input value="2007-12-01" type="text" class="vDateField" ' | |||
'<label for="">Date:</label> ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That the for is blank doesn't feel like a good test, could this widget be rendered for a field to have a value in the for attribute?
difficulty = models.CharField( | ||
max_length=20, choices=DIFFICULTY_CHOICES, null=True, blank=True | ||
) | ||
students = models.ManyToManyField(Student, blank=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To reduce the number of models, this could be:
students = models.ManyToManyField(Student, blank=True) | |
categories = models.ManyToManyField(Category, blank=True) |
And we remove the student model
If we can avoid adding a new model entirely, that would also be good
class CourseAdmin(admin.ModelAdmin): | ||
radio_fields = {"difficulty": admin.VERTICAL} | ||
filter_horizontal = ("students",) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class CourseAdmin(admin.ModelAdmin): | |
radio_fields = {"difficulty": admin.VERTICAL} | |
filter_horizontal = ("students",) |
This is not required for the test, you can just do site.register(Course)
@@ -39,4 +39,5 @@ QUnit.test('time zone offset warning', function(assert) { | |||
DateTimeShortcuts.init(); | |||
$('body').attr('data-admin-utc-offset', savedOffset); | |||
assert.equal($('.timezonewarning').text(), 'Note: You are 1 hour behind server time.'); | |||
assert.equal($('.timezonewarning').attr("id"), "_timezone_warning_helptext"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want to update this test to better cover the code:
const id = inp.id;
const field_id = inp.closest('p.datetime') ? id.slice(0, id.lastIndexOf("_")) : id;
warning.classList.add('help', warningClass);
warning.id = `${field_id}_timezone_warning_helptext`;
There are two cases here (which I believe might be a fieldset and normal field case)? I also don't like that the field id is not well formed in the test
Trac ticket number
ticket-35892
Branch description
continues PR..
Thank you to @sai-ganesh-03 for implementing the work, to @sarahboyce for offering guidance on the direction,
and to @knyghty for bringing up the issue 🥰
I updated the admin change form to use
<fieldset>
and<legend>
tags for fields whenuse_fieldset
is set to True.I also connected additional help texts within widgets using
aria-describedby
.Checklist
main
branch.