source: main/waeup.sirp/trunk/src/waeup/sirp/widgets/datewidget.py @ 6867

Last change on this file since 6867 was 6867, checked in by Henrik Bettermann, 13 years ago

Add FormattedDatetimeDisplayWidget?.

File size: 6.4 KB
Line 
1##
2## datewidget.py
3## Login : <uli@pu.smp.net>
4## Started on  Wed May 11 15:53:35 2011 Uli Fouquet
5## $Id$
6##
7## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22"""
23A datewidget with customizable date format.
24"""
25from datetime import datetime
26from zope.formlib.i18n import _
27from zope.formlib.interfaces import ConversionError, IDisplayWidget
28from zope.formlib.textwidgets import (
29    DateWidget, DateDisplayWidget, escape, DatetimeDisplayWidget)
30from zope.formlib.widget import renderElement, CustomWidgetFactory
31from zope.interface import implements
32
33class FormattedDateWidget(DateWidget):
34    """A date widget that supports different (and _explicit_) date formats.
35
36    This is an input widget.
37    """
38    date_format = '%Y-%m-%d'
39
40    def _toFieldValue(self, input):
41        if input == self._missing:
42            return self.context.missing_value
43        else:
44            try:
45                value = datetime.strptime(input, self.date_format)
46            except (ValueError, IndexError), v:
47                raise ConversionError(_("Invalid datetime data"), v)
48        return value.date()
49
50    def _toFormValue(self, value):
51        if value:
52            value = value.strftime(self.date_format)
53        return value
54
55class FormattedDateDisplayWidget(DateDisplayWidget):
56    """A date widget that supports different (and _explicit_) date formats.
57
58    This is a display widget.
59    """
60    date_format = '%Y-%m-%d'
61    implements(IDisplayWidget)
62   
63    def __call__(self):
64        if self._renderedValueSet():
65            content = self._data
66        else:
67            content = self.context.default
68        if content == self.context.missing_value:
69            return ""
70        content = content.strftime(self.date_format)
71        return renderElement("span", contents=escape(content),
72                             cssClass=self.cssClass)
73
74class FormattedDatetimeDisplayWidget(DatetimeDisplayWidget):
75    """A datetime widget that supports different (and _explicit_) date formats.
76
77    This is a display widget.
78    """
79    datetime_format = '%Y-%m-%d %H:%M:%S'
80    implements(IDisplayWidget)
81
82    def __call__(self):
83        if self._renderedValueSet():
84            content = self._data
85        else:
86            content = self.context.default
87        if content == self.context.missing_value:
88            return ""
89        content = content.strftime(self.datetime_format)
90        return renderElement("span", contents=escape(content),
91                             cssClass=self.cssClass)
92
93#: A dictionary of supported date formats.
94#:
95#: The following formats are supported:
96#:
97#: ``iso``
98#:    ISO format ``YYYY-MM-DD``
99#: ``le``
100#:    little endian with slashes: ``DD/MM/YYYY``
101#: ``de``
102#:    german date format: ``DD.MM.YYYY``
103#: ``us``
104#:    middle endian format common in the U.S.: ``MM/DD/YYYY``
105#:
106#: Furthermore we support for input widgets an additional year
107#: marker. Input date widgets with this marker provide also a year
108#: selector, handy for dates of birth etc.
109#:
110#: The year-supporting formats are similar to the basic versions above:
111#:
112#: ``iso-year``
113#:    ISO format ``YYYY-MM-DD``
114#: ``le-year``
115#:    little endian with slashes: ``DD/MM/YYYY``
116#: ``de-year``
117#:    german date format: ``DD.MM.YYYY``
118#: ``us-year``
119#:    middle endian format common in the U.S.: ``MM/DD/YYYY``
120#:   
121#: For date display widgets there is naturally no difference between a
122#: year and non-year setting (you can for instance use 'le' or 'le-year'
123#: with the same output).
124DATE_FORMATS = {
125    'iso': ('datepicker', '%Y-%m-%d'),
126    'le':  ('datepicker-le', '%d/%m/%Y'),
127    'de':  ('datepicker-de', '%d.%m.%Y'),
128    'us':  ('datepicker-us', '%m/%d/%Y'),
129    'iso-year': ('datepicker-year', '%Y-%m-%d'),
130    'le-year':  ('datepicker-le-year', '%d/%m/%Y'),
131    'de-year':  ('datepicker-de-year', '%d.%m.%Y'),
132    'us-year':  ('datepicker-us-year', '%m/%d/%Y'),
133    }
134def FriendlyDateWidget(format):
135    """Get a friendly date input widget for `format`.
136
137    This widget is suitable for edit and add forms.
138   
139    Valid `format` values are the keys of :var:`DATE_FORMATS`
140    dict. Default is ``le`` (little endian; DD/MM/YYYY).
141
142    Friendly date widgets are rendered with a specialized CSS tag for
143    enabling JavaScript datepickers.
144    """
145    css_class, date_format = DATE_FORMATS.get(format, DATE_FORMATS['le'])
146    return CustomWidgetFactory(
147        FormattedDateWidget,
148        cssClass=css_class,
149        date_format=date_format)
150
151def FriendlyDateDisplayWidget(format):
152    """Get a friendly date display widget for `format`.
153
154    This widget is suitable for display forms.
155   
156    Valid `format` values are the keys of :var:`DATE_FORMATS`
157    dict. Default is ``le`` (little endian; DD/MM/YYYY).
158
159    This widget is not rendered with a specialized CSS tag for
160    enabling JavaScript datepickers. `css_class` is ignored which means
161    there is nor difference between e.g. ``le`` and ``le-year``.`
162    """
163    css_class, date_format = DATE_FORMATS.get(format, DATE_FORMATS['le'])
164    return CustomWidgetFactory(
165        FormattedDateDisplayWidget,
166        date_format=date_format)
167
168def FriendlyDatetimeDisplayWidget(format):
169    """Get a friendly datetime display widget for `format`.
170
171    This widget is suitable for display forms.
172
173    Valid `format` values are the keys of :var:`DATE_FORMATS`
174    dict. Default is ``le`` (little endian; DD/MM/YYYY).
175
176    This widget is not rendered with a specialized CSS tag for
177    enabling JavaScript datepickers. `css_class` is ignored which means
178    there is nor difference between e.g. ``le`` and ``le-year``.`
179    """
180    css_class, date_format = DATE_FORMATS.get(format, DATE_FORMATS['le'])
181    datetime_format = date_format + ' %H:%M:%S'
182    return CustomWidgetFactory(
183        FormattedDatetimeDisplayWidget,
184        datetime_format=datetime_format)
Note: See TracBrowser for help on using the repository browser.