Skip to content

Instantly share code, notes, and snippets.

@katjakarhu
Created December 8, 2011 11:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save katjakarhu/1446772 to your computer and use it in GitHub Desktop.
Save katjakarhu/1446772 to your computer and use it in GitHub Desktop.
HTML5 Django DateTimeWidget
See rest of the code and instructions at:
http://copiesofcopies.org/webl/ ( http://copiesofcopies.org/webl/2010/04/26/a-better-datetime-widget-for-django/ )
For localized times, use with django-timezones:
from timezones.forms import LocalizedDateTimeField
date_field = LocalizedDateTimeField(
timezone=target_timezone,
widget=JqSplitDateTimeWidget(
attrs={'date_class':'datepicker','time_class':'timepicker'}
)
)
# fields.py
from time import strptime, strftime
from django import forms
from django.db import models
from django.forms import fields
from conflux.widgets import JqSplitDateTimeWidget
class JqSplitDateTimeField(fields.MultiValueField):
widget = JqSplitDateTimeWidget
def __init__(self, *args, **kwargs):
"""
Have to pass a list of field types to the constructor, else we
won't get any data to our compress method.
"""
all_fields = (
fields.CharField(max_length=10),
fields.TimeField(),
)
super(JqSplitDateTimeField, self).__init__(all_fields, *args, **kwargs)
def compress(self, data_list):
"""
Takes the values from the MultiWidget and passes them as a
list to this function. This function needs to compress the
list into a single object to save.
"""
if data_list:
if not (data_list[0] and data_list[1]):
raise forms.ValidationError("Field is missing data.")
input_time = strptime("%s"%(data_list[1]), "%I:%M %p")
datetime_string = "%s %s" % (data_list[0], strftime('%H:%M', input_time))
print "Datetime: %s"%datetime_string
return datetime_string
return None
# widgets.py
from django import forms
from django.db import models
from django.template.loader import render_to_string
from django.forms.widgets import Select, MultiWidget, DateInput, TextInput, TimeInput
from time import strftime
class HTML5TimeInput(TimeInput):
def __init__(self, itype, attrs):
self.input_type = itype
super(HTML5TimeInput, self).__init__(attrs)
class HTML5DateInput(DateInput):
def __init__(self, itype, attrs, format):
self.input_type = itype
super(HTML5DateInput, self).__init__(attrs)
class JqSplitDateTimeWidget(MultiWidget):
def __init__(self, attrs=None, date_format=None, time_format=None):
date_class = attrs['date_class']
time_class = attrs['time_class']
del attrs['date_class']
del attrs['time_class']
time_attrs = attrs.copy()
time_attrs['class'] = time_class
date_attrs = attrs.copy()
date_attrs['class'] = date_class
widgets = (HTML5DateInput(itype="date", attrs=date_attrs, format=date_format), HTML5TimeInput(itype="time", attrs=time_attrs))
super(JqSplitDateTimeWidget, self).__init__(widgets, attrs)
def decompress(self, value):
if value:
d = strftime("%Y-%m-%d", value.timetuple())
hour = strftime("%H", value.timetuple())
minute = strftime("%M", value.timetuple())
meridian = strftime("%p", value.timetuple())
return (d, hour+":"+minute, meridian)
else:
return (None, None, None)
def format_output(self, rendered_widgets):
"""
Given a list of rendered widgets (as strings), it inserts an HTML
linebreak between them.
Returns a Unicode string representing the HTML for the whole lot.
"""
return "Date: %s<br/>Time: %s" % (rendered_widgets[0], rendered_widgets[1])
class Media:
css = {
}
js = (
"js/jqsplitdatetime.js",
)
@mattlinares
Copy link

Does this not include a timepicker UI? If so, I can't get it to work, if not, I spent a lot of time thinking is was and trying to get it to work, with the same mindset as a user expecting the time to be selected in the same way as the date. It might be worth pointing that out in the intro.

Thanks though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment