Skip to content

Commit

Permalink
Introduce new widgets that pick up locale date formats
Browse files Browse the repository at this point in the history
  • Loading branch information
codeinthehole committed May 30, 2013
1 parent a37c458 commit 25866bf
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 18 deletions.
22 changes: 9 additions & 13 deletions oscar/apps/dashboard/offers/forms.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import datetime

from django import forms

from django.db.models.loading import get_model
from django.utils.translation import ugettext_lazy as _

from oscar.forms import widgets

ConditionalOffer = get_model('offer', 'ConditionalOffer')
Condition = get_model('offer', 'Condition')
Benefit = get_model('offer', 'Benefit')
Expand All @@ -17,24 +18,19 @@ class Meta:


class RestrictionsForm(forms.ModelForm):
format = '%Y-%m-%d %H:%M'

# We use data attributes to specify the date and time formats in a notation
# that the JS datepicker uses.
widget = forms.DateTimeInput(
format=format, attrs={
'data-dateFormat': 'yy-mm-dd',
'data-timeFormat': 'HH:mm'
})

start_datetime = forms.DateTimeField(
widget=widget, label=_("Start date"), required=False)
widget=widgets.DateTimePickerInput(),
label=_("Start date"), required=False)
end_datetime = forms.DateTimeField(
widget=widget, label=_("End date"), required=False)
widget=widgets.DateTimePickerInput(),
label=_("End date"), required=False)

def __init__(self, *args, **kwargs):
super(RestrictionsForm, self).__init__(*args, **kwargs)
today = datetime.date.today()
self.fields['start_datetime'].initial = today.strftime(self.format)
self.fields['start_datetime'].initial = today.strftime(
self.fields['start_datetime'].widget.format)

class Meta:
model = ConditionalOffer
Expand Down
9 changes: 7 additions & 2 deletions oscar/apps/dashboard/vouchers/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from django.db.models.loading import get_model
from django.utils.translation import ugettext_lazy as _

from oscar.forms import widgets

Voucher = get_model('voucher', 'Voucher')
Benefit = get_model('offer', 'Benefit')
Range = get_model('offer', 'Range')
Expand All @@ -14,8 +16,11 @@ class VoucherForm(forms.Form):
"""
name = forms.CharField(label=_("Name"))
code = forms.CharField(label=_("Code"))
start_date = forms.DateField(label=_("Start date"))
end_date = forms.DateField(label=_("End date"))

start_date = forms.DateField(
label=_("Start date"), widget=widgets.DatePickerInput())
end_date = forms.DateField(
label=_("End date"), widget=widgets.DatePickerInput())
usage = forms.ChoiceField(choices=Voucher.USAGE_CHOICES, label=_("Usage"))

benefit_range = forms.ModelChoiceField(
Expand Down
76 changes: 76 additions & 0 deletions oscar/forms/widgets.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import re

from django.conf import settings
from django import forms
from django.template import Context
Expand Down Expand Up @@ -54,3 +56,77 @@ def __init__(self, *args, **kwargs):
kwargs['attrs'].setdefault('class', '')
kwargs['attrs']['class'] += ' wysiwyg'
super(WYSIWYGTextArea, self).__init__(*args, **kwargs)


def datetime_format_to_js_date_format(format):
"""
Convert a Python datetime format to a date format suitable for use with JS
date pickers
"""
converted = format
replacements = {
'%Y': 'yy',
'%m': 'mm',
'%d': 'dd',
'%H:%M': '',
}
for search, replace in replacements.iteritems():
converted = converted.replace(search, replace)
return converted.strip()


def datetime_format_to_js_time_format(format):
"""
Convert a Python datetime format to a time format suitable for use with JS
date pickers
"""
converted = format
replacements = {
'%Y': '',
'%m': '',
'%d': '',
'%H': 'HH',
'%M': 'mm',
}
for search, replace in replacements.iteritems():
converted = converted.replace(search, replace)

converted = re.sub('[-/][^%]', '', converted)

return converted.strip()


def add_js_formats(widget):
"""
Set data attributes for date and time format on a widget
"""
attrs = {
'data-dateFormat': datetime_format_to_js_date_format(
widget.format),
'data-timeFormat': datetime_format_to_js_time_format(
widget.format)
}
widget.attrs.update(attrs)


class DatePickerInput(forms.DateInput):
"""
DatePicker input that uses the jQuery UI datepicker. Data attributes are
used to pass the date format to the JS
"""
def __init__(self, *args, **kwargs):
super(DatePickerInput, self).__init__(*args, **kwargs)
add_js_formats(self)


class DateTimePickerInput(forms.DateTimeInput):
# Build a widget which uses the locale datetime format but without seconds.
# We also use data attributes to pass these formats to the JS datepicker.

def __init__(self, *args, **kwargs):
include_seconds = kwargs.pop('include_seconds', False)
super(DateTimePickerInput, self).__init__(*args, **kwargs)

if not include_seconds:
self.format = re.sub(':?%S', '', self.format)
add_js_formats(self)
8 changes: 5 additions & 3 deletions tests/unit/core/utils_tests.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
from django.test import TestCase
from django.test.utils import override_settings

from oscar.core.utils import slugify
from oscar.core import utils


class TestSlugify(TestCase):

def test_uses_custom_mappings(self):
mapping = {'c++': 'cpp'}
with override_settings(OSCAR_SLUG_MAP=mapping):
self.assertEqual('cpp', slugify('c++'))
self.assertEqual('cpp', utils.slugify('c++'))

def test_uses_blacklist(self):
blacklist = ['the']
with override_settings(OSCAR_SLUG_BLACKLIST=blacklist):
self.assertEqual('bible', slugify('The Bible'))
self.assertEqual('bible', utils.slugify('The Bible'))


Empty file added tests/unit/forms/__init__.py
Empty file.
32 changes: 32 additions & 0 deletions tests/unit/forms/widget_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import nose

from oscar.forms import widgets


def test_datetime_to_date_format_conversion():
format_testcases = (
('%Y-%m-%d', 'yy-mm-dd'),
('%Y-%m-%d %H:%M', 'yy-mm-dd'),
)

def compare(format, expected):
nose.tools.eq_(
widgets.datetime_format_to_js_date_format(format), expected)

for format, expected in format_testcases:
yield compare, format, expected


def test_datetime_to_time_format_conversion():
format_testcases = (
('%Y-%m-%d', ''),
('%Y-%m-%d %H:%M', 'HH:mm'),
('%d/%m/%Y', ''),
)

def compare(format, expected):
nose.tools.eq_(
widgets.datetime_format_to_js_time_format(format), expected)

for format, expected in format_testcases:
yield compare, format, expected

0 comments on commit 25866bf

Please sign in to comment.