Как стать автором
Обновить

Как легко сделать календарь и часы для ввода даты и времени на форму

Время на прочтение2 мин
Количество просмотров10K
а точнее использовать уже имеющиеся в Django (те что по-уполчанию есть в интерфейсе администрирования)…



Начал, естественно, с изучения того как это сделано в админке. Оказалось всё достаточно просто, но с парой поучительных примеров.

Во-первых, нашел где лежит этот красивый календарик и как он прилеплен к полю ввода: DateTimeShortcuts.js, в нём и инструкция:
// Inserts shortcut buttons after all of the following:
//     <input type="text" class="vDateField">
//     <input type="text" class="vTimeField">

Только потом правда оказалось, что этот файл не работает без других, а именно без i18n.js, core.js и calendar.js — их тоже надо включить в шаблон, который будет использоваться для отображения формы. А ещё файлы со стилями, по-моему их тоже было несколько, но я взял только необходимое и скопировал в свой calendar.css, чтобы потом спокойно модифицировать — настраивается там всё на ура. Скрипты я, кстати, тоже перетащил в свою папку, потому что с одной стороны как-то не серьёзно, когда что-то включается с путём /admin/, а с другой стороны «вдруг надо будет подправить» (понадобилось).

Следующим шагом было понять как реализован widget для раздельного ввода даты и времени (я, если честно, не знал что с точки зрения класса формы это одно поле с хитрым виджетом и планировал просто сделать 2 поля ввода TextInput и прописать им классы). Подход весьма элегантный:
class EventSplitDateTime(forms.SplitDateTimeWidget):
    def __init__(self, attrs=None):
        widgets = [forms.TextInput(attrs={'class': 'vDateField'}), 
                   forms.TextInput(attrs={'class': 'vTimeField'})]
        # Note that we're calling MultiWidget, not SplitDateTimeWidget, because
        # we want to define widgets.
        forms.MultiWidget.__init__(self, widgets, attrs)

    def format_output(self, rendered_widgets):
        return mark_safe(u'%s<br />%s' % (rendered_widgets[0], rendered_widgets[1]))

и, соответсвенно, использование становится элементарным:
class EventForm(forms.Form):
    start = forms.DateTimeField(label=ugettext("Start"), widget=EventSplitDateTime())
    end = forms.DateTimeField(label=ugettext("End"), widget=EventSplitDateTime())


Вот и всё :-) особо строго не судите. Как выглядит результат можно посмотреть тут.
Теги:
Хабы:
Всего голосов 14: ↑10 и ↓4+6
Комментарии6

Публикации

Работа

Ближайшие события