from django.template.loader import render_to_string
from taggit.forms import TagWidget
-import datetimewidget.widgets
from .models import (Emission, Episode, Diffusion, Schedule, SoundFile,
NewsItem, Absence, PlaylistElement)
-
-
-DATETIME_OPTIONS = {
- 'format': 'dd/mm/yyyy hh:ii',
- 'language': 'fr',
- 'weekStart': '1',
- 'autoclose': 'true',
- }
-
-DATE_OPTIONS = {
- 'format': 'dd/mm/yyyy',
- 'language': 'fr',
- 'weekStart': '1',
- 'autoclose': 'true',
- 'minView': '"month"',
- }
-
-
-class DateTimeWidget(datetimewidget.widgets.DateTimeWidget):
- def __init__(self, *args, **kwargs):
- super(DateTimeWidget, self).__init__(*args, options=DATETIME_OPTIONS, **kwargs)
-
- def format_output(self, rendered_widgets):
- rendered_widgets[0] += '<span class="add-on"><i class="icon-remove"></i></span>'
- return super(DateTimeWidget, self).format_output(rendered_widgets)
-
-
-class DateWidget(datetimewidget.widgets.DateTimeWidget):
- def __init__(self, *args, **kwargs):
- super(DateWidget, self).__init__(*args, options=DATE_OPTIONS, **kwargs)
-
- def format_output(self, rendered_widgets):
- rendered_widgets[0] += '<span class="add-on"><i class="icon-remove"></i></span>'
- return super(DateWidget, self).format_output(rendered_widgets)
-
- def value_from_datadict(self, data, files, name):
- t = super(DateWidget, self).value_from_datadict(data, files, name)
- if t:
- t = t.split()[0] # date only
- return t
+from .widgets import DateTimeWidget, DateWidget
def slugify(s):
--- /dev/null
+# Bootstrap django-datetime-widget is a simple and clean widget for DateField,
+# Timefiled and DateTimeField in Django framework. It is based on Bootstrap
+# datetime picker, supports Bootstrap 2
+#
+# https://github.com/asaglimbeni/django-datetime-widget
+#
+# License: BSD
+# Initial Author: Alfredo Saglimbeni
+
+import json
+import re
+import uuid
+
+from django.forms.widgets import DateTimeInput, DateInput, TimeInput, SelectMultiple
+from django.utils.formats import get_language
+from django.utils.safestring import mark_safe
+
+DATE_FORMAT_JS_PY_MAPPING = {
+ 'P': '%p',
+ 'ss': '%S',
+ 'ii': '%M',
+ 'hh': '%H',
+ 'HH': '%I',
+ 'dd': '%d',
+ 'mm': '%m',
+ 'yy': '%y',
+ 'yyyy': '%Y',
+}
+
+DATE_FORMAT_TO_PYTHON_REGEX = re.compile(r'\b(' + '|'.join(DATE_FORMAT_JS_PY_MAPPING.keys()) + r')\b')
+
+
+DATE_FORMAT_PY_JS_MAPPING = {
+ '%M': 'ii',
+ '%m': 'mm',
+ '%I': 'HH',
+ '%H': 'hh',
+ '%d': 'dd',
+ '%Y': 'yyyy',
+ '%y': 'yy',
+ '%p': 'P',
+ '%S': 'ss'
+}
+
+DATE_FORMAT_TO_JS_REGEX = re.compile(r'(?<!\w)(' + '|'.join(DATE_FORMAT_PY_JS_MAPPING.keys()) + r')\b')
+
+
+BOOTSTRAP_INPUT_TEMPLATE = """
+ <div id="%(id)s" class="controls input-append date">
+ %(rendered_widget)s
+ %(clear_button)s
+ <span class="add-on"><i class="icon-th"></i></span>
+ </div>
+ <script type="text/javascript">
+ $("#%(id)s").datetimepicker({%(options)s});
+ </script>
+ """
+
+CLEAR_BTN_TEMPLATE = """<span class="add-on"><i class="icon-remove"></i></span>"""
+
+
+class PickerWidgetMixin(object):
+
+ format_name = None
+ glyphicon = None
+
+ def __init__(self, attrs=None, options=None, usel10n=None):
+
+ if attrs is None:
+ attrs = {'readonly': ''}
+
+ self.options = options
+ if get_language():
+ self.options['language'] = get_language().split('-')[0]
+
+ # We're not doing localisation, get the Javascript date format provided by the user,
+ # with a default, and convert it to a Python data format for later string parsing
+ date_format = self.options['format']
+ self.format = DATE_FORMAT_TO_PYTHON_REGEX.sub(
+ lambda x: DATE_FORMAT_JS_PY_MAPPING[x.group()],
+ date_format
+ )
+
+ super(PickerWidgetMixin, self).__init__(attrs, format=self.format)
+
+ def render(self, name, value, attrs=None):
+ final_attrs = self.build_attrs(attrs)
+ rendered_widget = super(PickerWidgetMixin, self).render(name, value, final_attrs)
+
+ #if not set, autoclose have to be true.
+ self.options.setdefault('autoclose', True)
+
+ # Build javascript options out of python dictionary
+ options_list = []
+ for key, value in iter(self.options.items()):
+ options_list.append("%s: %s" % (key, json.dumps(value)))
+
+ js_options = ",\n".join(options_list)
+
+ # Use provided id or generate hex to avoid collisions in document
+ id = final_attrs.get('id', uuid.uuid4().hex)
+
+ return mark_safe(BOOTSTRAP_INPUT_TEMPLATE % dict(
+ id=id,
+ rendered_widget=rendered_widget,
+ clear_button=CLEAR_BTN_TEMPLATE if self.options.get('clearBtn') else '',
+ glyphicon=self.glyphicon,
+ options=js_options
+ )
+ )
+
+
+class DateTimeWidget(PickerWidgetMixin, DateTimeInput):
+ """
+ DateTimeWidget is the corresponding widget for Datetime field, it renders both the date and time
+ sections of the datetime picker.
+ """
+
+ format_name = 'DATETIME_INPUT_FORMATS'
+ glyphicon = 'glyphicon-th'
+
+ def __init__(self, attrs=None, options=None, usel10n=None):
+
+ if options is None:
+ options = {}
+
+ # Set the default options to show only the datepicker object
+ options['format'] = options.get('format', 'dd/mm/yyyy hh:ii')
+
+ super(DateTimeWidget, self).__init__(attrs, options, usel10n)
+
+
+class DateWidget(PickerWidgetMixin, DateInput):
+ """
+ DateWidget is the corresponding widget for Date field, it renders only the date section of
+ datetime picker.
+ """
+
+ format_name = 'DATE_INPUT_FORMATS'
+ glyphicon = 'glyphicon-calendar'
+
+ def __init__(self, attrs=None, options=None, usel10n=None):
+
+ if options is None:
+ options = {}
+
+ # Set the default options to show only the datepicker object
+ options['startView'] = options.get('startView', 2)
+ options['minView'] = options.get('minView', 2)
+ options['format'] = options.get('format', 'dd/mm/yyyy')
+
+ super(DateWidget, self).__init__(attrs, options, usel10n)
+
+
+
+class TimeWidget(TimeInput):
+ """
+ TimeWidget is a widget for time selection, it uses the HTML5 "time"
+ input type and has a bit of a fallback mechanism with the presence
+ of the pattern attribute in case a standard text input is used.
+ """
+ input_type = 'time'
+
+ def __init__(self, **kwargs):
+ super(TimeWidget, self).__init__(**kwargs)
+ self.attrs['step'] = '300' # 5 minutes
+ self.attrs['pattern'] = '[0-9]{2}:[0-9]{2}'
+
+
+class WeekdaysWidget(SelectMultiple):
+ def render(self, name, value, attrs=None, choices=()):
+ s = []
+ value = value or []
+ for choice_id, choice_label in self.choices:
+ s.append('<li><label><input type="checkbox" '
+ ' name="%(name)s-%(choice_id)s" %(checked)s>'
+ '<span>%(choice_label)s</span></label></li>' % {
+ 'name': name,
+ 'checked': 'checked' if choice_id in value else '',
+ 'choice_id': choice_id,
+ 'choice_label': choice_label})
+ return mark_safe('<ul id="%(id)s">' % attrs + '\n'.join(s) + '</ul>')
+
+ def value_from_datadict(self, data, files, name):
+ choices = []
+ for choice_id, choice_label in self.choices:
+ if data.get('%s-%s' % (name, choice_id)):
+ choices.append(choice_id)
+ return choices