== Background
The `forms.DateField` uses a
[https://docs.djangoproject.com/en/3.2/ref/forms/widgets/#dateinput
forms.widgets.DateInput] widget, which renders as a standard `<input
style="text">` in HTML (a simple text box).
It would be very convenient if this widget could provide a date picker by
default, similar to date fields on the Django admin site, for example.
There are several options here:
- One could use the
[https://docs.djangoproject.com/en/3.2/ref/forms/widgets/#selectdatewidget
forms.widgets.SelectDateWidget], but that is not as convenient as a proper
calendar date picker.
- One could use the Django
[https://github.com/django/django/blob/main/django/contrib/admin/widgets.py#L49
admin date (and/or time) widgets], but, as far as I know, the admin
widgets are not part of the public API, and getting them to work can be a
puzzle.
- There are also third-party apps that implement date pickers, but those
introduce additional dependencies.
- Last, but not least, [[https://developer.mozilla.org/en-
US/docs/Web/HTML/Element/input/date#browser_compatibility | modern
browsers support the HTML `<input style="date">` element]], which provides
a very clean solution to the problem described above, without any custom
CSS or JavaScript.
Although it is not too difficult to implement a custom widget that uses
`<input style="date">`, one would need to know about it existence first.
== Feature request
Would it be possible to provide something like a
`forms.widgets.BrowserDateInput` that leverages `<input style="date">`?
A crude implementation could look like this:
{{{
class BrowserDateInput(forms.widgets.DateInput):
def get_context(self, name, value, attrs):
context = super().get_context(name, value, attrs)
context['widget']['type'] = 'date'
return context
}}}
To set current date and/or minimum/maximum allowable date, we can use the
`attrs` argument. For example:
{{{
BrowserDateInput(attrs=dict(value=self.today, min=self.today))
}}}
Note that the browser automatically takes care of client-side field
validation.
P.S. a similar request could be made for a `BrowserTimeInput`.
--
Ticket URL: <https://code.djangoproject.com/ticket/33100>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
Ticket URL: <https://code.djangoproject.com/ticket/33100#comment:1>
--
Ticket URL: <https://code.djangoproject.com/ticket/33100#comment:2>
Old description:
New description:
== Background
== Feature request
{{{
BrowserDateInput(attrs=dict(value=self.today, min=self.today))
}}}
P.S. a similar request could be made for a `BrowserTimeInput`, although
localization could complicate matters here (haven't looked into that yet).
--
--
Ticket URL: <https://code.djangoproject.com/ticket/33100#comment:3>
* status: new => closed
* resolution: => duplicate
Comment:
Duplicate of #21470. If the concerns there are no longer an issue, we
could reopen that ticket.
--
Ticket URL: <https://code.djangoproject.com/ticket/33100#comment:4>
Comment (by dvg):
Replying to [comment:4 Tim Graham]:
> Duplicate of #21470. If the concerns there are no longer an issue, we
could reopen that ticket.
Although I am not quite sure if the concerns from that ticket (or
[https://code.djangoproject.com/ticket/16630#comment:11 from 16630]) are
still valid (they were raised ten years ago), to my untrained eye
[[https://developer.mozilla.org/en-
US/docs/Web/HTML/Element/input/date#browser_compatibility | browser
support for `<input style="date">`]] looks pretty solid now.
Regardless, my proposal is **not** to modify the existing `DateInput`, but
rather to introduce a **new** widget called e.g. `BrowserDateInput`.
- this circumvents any backward compatibility issues
- the class name gives a clear indication of what the new widget does
- looks like a relatively minor effort, which could nevertheless be of
great help to many people (considering the number of related questions on
the web).
It would be great if this ticket could be re-opened. :-)
--
Ticket URL: <https://code.djangoproject.com/ticket/33100#comment:5>
Comment (by Tim Graham):
I doubt there would be consensus to add unused widgets in Django,
especially when the implementation is so trivial:
{{{#!python
from django import forms
class DateInput(forms.DateInput):
input_type = 'date'
}}}
or even: `DateInput(attrs={'type': 'date'})`
but you could write to the DevelopersMailingList to reach a wider
audience.
--
Ticket URL: <https://code.djangoproject.com/ticket/33100#comment:6>
Comment (by Claude Paroz):
I think it would be interesting to complete the `DateInput` documentation
explaining that and giving the small code excerpt given by Tim.
--
Ticket URL: <https://code.djangoproject.com/ticket/33100#comment:7>
Comment (by dvg):
Replying to [comment:7 Claude Paroz]:
> I think it would be interesting to complete the `DateInput`
documentation explaining that and giving the small code excerpt given by
Tim.
I agree.
The implementation is indeed trivial, as Tim Graham's example proves.
However, one cannot implement something that one does not know about.
Therefore, I think an example in the documentation would be very helpful.
--
Ticket URL: <https://code.djangoproject.com/ticket/33100#comment:8>
Comment (by Steven Mapes):
It should be noted that just changing the type attribute is **not** all
you need to do in order to use the date and time inputs correctly within
Django. Whilst doing that will render the HTML input it will not pickup
the initial values correctly as you need to format them into the right
input format, normally by using isoformat() on either the initial or
instance value depending on whether you are using a standard form or model
form.
The "datetime-local" input will work okay without any other changes.
For the sake of anyone coming back to this ticket in the future here's one
way of subclassing the DateInput and TimeInput widgets with the updated
render method that will mean you can then use these as you would standard
widgets and won't hit the issues described above
{{{
class DateInputPicker(DateInput):
input_type = "date"
def render(self, name, value, attrs=None, renderer=None):
"""Render the widget as an HTML string."""
value = value.isoformat() if value and isinstance(value, date)
else value
context = self.get_context(name, value, attrs)
return self._render(self.template_name, context, renderer)
class TimeInputPicker(TimeInput):
input_type = "time"
def render(self, name, value, attrs=None, renderer=None):
"""Render the widget as an HTML string."""
value = value.isoformat() if value and isinstance(value, date)
else value
context = self.get_context(name, value, attrs)
return self._render(self.template_name, context, renderer)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/33100#comment:9>