Fixed #29056 -- Fixed HTML5 validation of required SelectDateWidget.

placeholder is required for "select" with "required" attribute.
This commit is contained in:
Hasan Ramezani 2019-05-05 01:26:37 +02:00 committed by Mariusz Felisiak
parent ef9f2eb69c
commit f038214d91
3 changed files with 59 additions and 3 deletions

View File

@ -979,7 +979,11 @@ class SelectDateWidget(Widget):
date_context['year'] = self.select_widget(attrs, choices=year_choices).get_context( date_context['year'] = self.select_widget(attrs, choices=year_choices).get_context(
name=year_name, name=year_name,
value=context['widget']['value']['year'], value=context['widget']['value']['year'],
attrs={**context['widget']['attrs'], 'id': 'id_%s' % year_name}, attrs={
**context['widget']['attrs'],
'id': 'id_%s' % year_name,
'placeholder': _('Year') if self.is_required else False,
},
) )
month_choices = list(self.months.items()) month_choices = list(self.months.items())
if not self.is_required: if not self.is_required:
@ -988,7 +992,11 @@ class SelectDateWidget(Widget):
date_context['month'] = self.select_widget(attrs, choices=month_choices).get_context( date_context['month'] = self.select_widget(attrs, choices=month_choices).get_context(
name=month_name, name=month_name,
value=context['widget']['value']['month'], value=context['widget']['value']['month'],
attrs={**context['widget']['attrs'], 'id': 'id_%s' % month_name}, attrs={
**context['widget']['attrs'],
'id': 'id_%s' % month_name,
'placeholder': _('Month') if self.is_required else False,
},
) )
day_choices = [(i, i) for i in range(1, 32)] day_choices = [(i, i) for i in range(1, 32)]
if not self.is_required: if not self.is_required:
@ -997,7 +1005,11 @@ class SelectDateWidget(Widget):
date_context['day'] = self.select_widget(attrs, choices=day_choices,).get_context( date_context['day'] = self.select_widget(attrs, choices=day_choices,).get_context(
name=day_name, name=day_name,
value=context['widget']['value']['day'], value=context['widget']['value']['day'],
attrs={**context['widget']['attrs'], 'id': 'id_%s' % day_name}, attrs={
**context['widget']['attrs'],
'id': 'id_%s' % day_name,
'placeholder': _('Day') if self.is_required else False,
},
) )
subwidgets = [] subwidgets = []
for field in self._parse_date_fmt(): for field in self._parse_date_fmt():

View File

@ -373,6 +373,10 @@ Miscellaneous
* Support for ``pywatchman`` < 1.2.0 is removed. * Support for ``pywatchman`` < 1.2.0 is removed.
* HTML rendered by :class:`~django.forms.SelectDateWidget` for required fields
now have the ``placeholder`` attribute, which mainly may require some
adjustments in tests that compare HTML.
.. _deprecated-features-3.0: .. _deprecated-features-3.0:
Features deprecated in 3.0 Features deprecated in 3.0

View File

@ -314,6 +314,46 @@ class SelectDateWidgetTest(WidgetTest):
self.assertFalse(GetNotRequiredDate().fields['mydate'].widget.is_required) self.assertFalse(GetNotRequiredDate().fields['mydate'].widget.is_required)
self.assertTrue(GetRequiredDate().fields['mydate'].widget.is_required) self.assertTrue(GetRequiredDate().fields['mydate'].widget.is_required)
def test_selectdate_required_placeholder(self):
for required in (True, False):
field = DateField(widget=SelectDateWidget(years=('2018', '2019')), required=required)
self.check_html(field.widget, 'my_date', '', html=(
"""
<select name="my_date_month" id="id_my_date_month" %(m_placeholder)s>
%(empty)s
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
<option value="4">April</option>
<option value="5">May</option>
<option value="6">June</option>
<option value="7">July</option>
<option value="8">August</option>
<option value="9">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
<select name="my_date_day" id="id_my_date_day" %(d_placeholder)s>
%(empty)s
%(days_options)s
</select>
<select name="my_date_year" id="id_my_date_year" %(y_placeholder)s>
%(empty)s
<option value="2018">2018</option>
<option value="2019">2019</option>
</select>
""" % {
'days_options': '\n'.join(
'<option value="%s">%s</option>' % (i, i) for i in range(1, 32)
),
'm_placeholder': 'placeholder="Month"' if required else '',
'd_placeholder': 'placeholder="Day"' if required else '',
'y_placeholder': 'placeholder="Year"' if required else '',
'empty': '' if required else '<option selected value="">---</option>',
}
))
def test_selectdate_empty_label(self): def test_selectdate_empty_label(self):
w = SelectDateWidget(years=('2014',), empty_label='empty_label') w = SelectDateWidget(years=('2014',), empty_label='empty_label')