|
1 ### -*- coding: utf-8 -*- #################################################### |
|
2 ############################################################################## |
|
3 # |
|
4 # Copyright (c) 2012 Thierry Florac <tflorac AT ulthar.net> |
|
5 # All Rights Reserved. |
|
6 # |
|
7 # This software is subject to the provisions of the Zope Public License, |
|
8 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. |
|
9 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
|
10 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
11 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
|
12 # FOR A PARTICULAR PURPOSE. |
|
13 # |
|
14 ############################################################################## |
|
15 |
|
16 |
|
17 # import standard packages |
|
18 |
|
19 # import Zope3 interfaces |
|
20 from z3c.form.interfaces import IMultiWidget, IFieldWidget, NO_VALUE |
|
21 |
|
22 # import local interfaces |
|
23 from ztfy.skin.layer import IZTFYBrowserLayer |
|
24 from ztfy.utils.schema import IDatesRangeField |
|
25 |
|
26 # import Zope3 packages |
|
27 from z3c.form.browser.widget import HTMLFormElement |
|
28 from z3c.form.converter import SequenceDataConverter, FormatterValidationError |
|
29 from z3c.form.widget import FieldWidget, Widget |
|
30 from zope.component import adapter, adapts |
|
31 from zope.interface import implementer, implements |
|
32 from zope.i18n.format import DateTimeParseError |
|
33 |
|
34 # import local packages |
|
35 from ztfy.jqueryui import jquery_datetime |
|
36 |
|
37 |
|
38 class IDatesRangeWidget(IMultiWidget): |
|
39 """Dates range widget interface""" |
|
40 |
|
41 |
|
42 class DatesRangeDataConverter(SequenceDataConverter): |
|
43 """Dates range data converter""" |
|
44 |
|
45 adapts(IDatesRangeField, IDatesRangeWidget) |
|
46 |
|
47 def toWidgetValue(self, value): |
|
48 if value is self.field.missing_value: |
|
49 return (u'', u'') |
|
50 locale = self.widget.request.locale |
|
51 formatter = locale.dates.getFormatter('date', 'short') |
|
52 return (formatter.format(value[0]) if value[0] else None, |
|
53 formatter.format(value[1]) if value[1] else None) |
|
54 |
|
55 def toFieldValue(self, value): |
|
56 if not value: |
|
57 return self.field.missing_value |
|
58 try: |
|
59 locale = self.widget.request.locale |
|
60 formatter = locale.dates.getFormatter('date', 'short') |
|
61 return (formatter.parse(value[0]) if value[0] else None, |
|
62 formatter.parse(value[1]) if value[1] else None) |
|
63 except DateTimeParseError, err: |
|
64 raise FormatterValidationError(err.args[0], value) |
|
65 |
|
66 |
|
67 class DatesRangeWidget(HTMLFormElement, Widget): |
|
68 """Dates range widget""" |
|
69 |
|
70 implements(IDatesRangeWidget) |
|
71 |
|
72 @property |
|
73 def pattern(self): |
|
74 result = self.request.locale.dates.getFormatter('date', 'short').getPattern() |
|
75 return result.replace('dd', '%d').replace('MM', '%m').replace('yy', '%y') |
|
76 |
|
77 @property |
|
78 def begin_id(self): |
|
79 return '%s-begin' % self.id |
|
80 |
|
81 @property |
|
82 def begin_name(self): |
|
83 return '%s.begin' % self.name |
|
84 |
|
85 @property |
|
86 def begin_date(self): |
|
87 return (self.value[0] or '') if self.value else '' |
|
88 |
|
89 @property |
|
90 def end_id(self): |
|
91 return '%s-end' % self.id |
|
92 |
|
93 @property |
|
94 def end_name(self): |
|
95 return '%s.end' % self.name |
|
96 |
|
97 @property |
|
98 def end_date(self): |
|
99 return (self.value[1] or '') if self.value else '' |
|
100 |
|
101 def extract(self, default=NO_VALUE): |
|
102 begin_date = self.request.get(self.begin_name) |
|
103 end_date = self.request.get(self.end_name) |
|
104 return (begin_date, end_date) |
|
105 |
|
106 def render(self): |
|
107 result = super(DatesRangeWidget, self).render() |
|
108 if result: |
|
109 jquery_datetime.need() |
|
110 return result |
|
111 |
|
112 @adapter(IDatesRangeField, IZTFYBrowserLayer) |
|
113 @implementer(IFieldWidget) |
|
114 def DatesRangeFieldWidgetFactory(field, request): |
|
115 """IDatesRangeField widget factory""" |
|
116 return FieldWidget(field, DatesRangeWidget(request)) |