source: main/waeup.sirp/branches/henrik-bootstrap/src/waeup/sirp/widgets/datewidget.py @ 9003

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

More copyright adjustments (job finished).

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