mirror of
https://github.com/pretix/pretix.git
synced 2026-05-07 15:34:02 +00:00
A11y: add role=group and labels to multi-widgets (#2006)
* add role=group aria-labelledby to multiwidgets * remove for-attribute from parent-label for grouped inputs * add aria-labels to PhoneNumber-fields * add aria-label to name multi-inputs
This commit is contained in:
committed by
GitHub
parent
11f23c3fd2
commit
adddc7a71e
@@ -122,6 +122,8 @@ class NamePartsWidget(forms.MultiWidget):
|
|||||||
these_attrs.pop('data-no-required-attr', None)
|
these_attrs.pop('data-no-required-attr', None)
|
||||||
these_attrs['autocomplete'] = (self.attrs.get('autocomplete', '') + ' ' + self.autofill_map.get(self.scheme['fields'][i][0], 'off')).strip()
|
these_attrs['autocomplete'] = (self.attrs.get('autocomplete', '') + ' ' + self.autofill_map.get(self.scheme['fields'][i][0], 'off')).strip()
|
||||||
these_attrs['data-size'] = self.scheme['fields'][i][2]
|
these_attrs['data-size'] = self.scheme['fields'][i][2]
|
||||||
|
if len(self.widgets) > 1:
|
||||||
|
these_attrs['aria-label'] = self.scheme['fields'][i][1]
|
||||||
else:
|
else:
|
||||||
these_attrs = final_attrs
|
these_attrs = final_attrs
|
||||||
output.append(widget.render(name + '_%s' % i, widget_value, these_attrs, renderer=renderer))
|
output.append(widget.render(name + '_%s' % i, widget_value, these_attrs, renderer=renderer))
|
||||||
@@ -220,7 +222,7 @@ class WrappedPhonePrefixSelect(Select):
|
|||||||
country_name = locale.territories.get(country_code)
|
country_name = locale.territories.get(country_code)
|
||||||
if country_name:
|
if country_name:
|
||||||
choices.append((prefix, "{} {}".format(country_name, prefix)))
|
choices.append((prefix, "{} {}".format(country_name, prefix)))
|
||||||
super().__init__(choices=sorted(choices, key=lambda item: item[1]))
|
super().__init__(choices=sorted(choices, key=lambda item: item[1]), attrs={'aria-label': pgettext_lazy('phonenumber', 'International area code')})
|
||||||
|
|
||||||
def render(self, name, value, *args, **kwargs):
|
def render(self, name, value, *args, **kwargs):
|
||||||
return super().render(name, value or self.initial, *args, **kwargs)
|
return super().render(name, value or self.initial, *args, **kwargs)
|
||||||
@@ -243,7 +245,10 @@ class WrappedPhonePrefixSelect(Select):
|
|||||||
class WrappedPhoneNumberPrefixWidget(PhoneNumberPrefixWidget):
|
class WrappedPhoneNumberPrefixWidget(PhoneNumberPrefixWidget):
|
||||||
|
|
||||||
def __init__(self, attrs=None, initial=None):
|
def __init__(self, attrs=None, initial=None):
|
||||||
widgets = (WrappedPhonePrefixSelect(initial), forms.TextInput())
|
attrs = {
|
||||||
|
'aria-label': pgettext_lazy('phonenumber', 'Phone number (without international area code)')
|
||||||
|
}
|
||||||
|
widgets = (WrappedPhonePrefixSelect(initial), forms.TextInput(attrs=attrs))
|
||||||
super(PhoneNumberPrefixWidget, self).__init__(widgets, attrs)
|
super(PhoneNumberPrefixWidget, self).__init__(widgets, attrs)
|
||||||
|
|
||||||
def render(self, name, value, attrs=None, renderer=None):
|
def render(self, name, value, attrs=None, renderer=None):
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
from bootstrap3.renderers import FieldRenderer
|
from bootstrap3.renderers import FieldRenderer
|
||||||
from bootstrap3.text import text_value
|
from bootstrap3.text import text_value
|
||||||
from bootstrap3.utils import add_css_class
|
from bootstrap3.utils import add_css_class
|
||||||
from django.forms import CheckboxInput
|
from django.forms import CheckboxInput, CheckboxSelectMultiple, RadioSelect
|
||||||
from django.forms.utils import flatatt
|
from django.forms.utils import flatatt
|
||||||
from django.utils.html import escape, format_html, strip_tags
|
from django.utils.html import escape, format_html, strip_tags
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.translation import pgettext
|
from django.utils.translation import pgettext
|
||||||
|
|
||||||
|
|
||||||
def render_label(content, label_for=None, label_class=None, label_title='', optional=False, is_valid=None):
|
def render_label(content, label_for=None, label_class=None, label_title='', label_id='', optional=False, is_valid=None):
|
||||||
"""
|
"""
|
||||||
Render a label with content
|
Render a label with content
|
||||||
"""
|
"""
|
||||||
@@ -19,6 +19,8 @@ def render_label(content, label_for=None, label_class=None, label_title='', opti
|
|||||||
attrs['class'] = label_class
|
attrs['class'] = label_class
|
||||||
if label_title:
|
if label_title:
|
||||||
attrs['title'] = label_title
|
attrs['title'] = label_title
|
||||||
|
if label_id:
|
||||||
|
attrs['id'] = label_id
|
||||||
|
|
||||||
opt = ""
|
opt = ""
|
||||||
|
|
||||||
@@ -53,6 +55,7 @@ class CheckoutFieldRenderer(FieldRenderer):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
kwargs['layout'] = 'horizontal'
|
kwargs['layout'] = 'horizontal'
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
self.is_group_widget = isinstance(self.widget, (CheckboxSelectMultiple, RadioSelect, )) or (self.is_multi_widget and len(self.widget.widgets) > 1)
|
||||||
|
|
||||||
def get_form_group_class(self):
|
def get_form_group_class(self):
|
||||||
form_group_class = self.form_group_class
|
form_group_class = self.form_group_class
|
||||||
@@ -105,10 +108,19 @@ class CheckoutFieldRenderer(FieldRenderer):
|
|||||||
is_valid = len(self.field.errors) == 0
|
is_valid = len(self.field.errors) == 0
|
||||||
else:
|
else:
|
||||||
is_valid = None
|
is_valid = None
|
||||||
|
|
||||||
|
if self.is_group_widget:
|
||||||
|
label_for= ""
|
||||||
|
label_id = "legend-{}".format(self.field.html_name)
|
||||||
|
else:
|
||||||
|
label_for=self.field.id_for_label
|
||||||
|
label_id = ""
|
||||||
|
|
||||||
html = render_label(
|
html = render_label(
|
||||||
label,
|
label,
|
||||||
label_for=self.field.id_for_label,
|
label_for=label_for,
|
||||||
label_class=self.get_label_class(),
|
label_class=self.get_label_class(),
|
||||||
|
label_id=label_id,
|
||||||
optional=not required and not isinstance(self.widget, CheckboxInput),
|
optional=not required and not isinstance(self.widget, CheckboxInput),
|
||||||
is_valid=is_valid
|
is_valid=is_valid
|
||||||
) + html
|
) + html
|
||||||
@@ -121,3 +133,10 @@ class CheckoutFieldRenderer(FieldRenderer):
|
|||||||
label_for=self.field.id_for_label,
|
label_for=self.field.id_for_label,
|
||||||
label_title=escape(strip_tags(self.field_help)),
|
label_title=escape(strip_tags(self.field_help)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def wrap_label_and_field(self, html):
|
||||||
|
if self.is_group_widget:
|
||||||
|
attrs = ' role="group" aria-labelledby="legend-{}"'.format(self.field.html_name)
|
||||||
|
else:
|
||||||
|
attrs = ''
|
||||||
|
return '<div class="{klass}"{attrs}>{html}</div>'.format(klass=self.get_form_group_class(), html=html, attrs=attrs)
|
||||||
|
|||||||
Reference in New Issue
Block a user