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

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

Adjust some docstrings.

  • Property svn:keywords set to Id
File size: 5.9 KB
Line 
1## $Id: datewidget.py 7599 2012-02-07 11:30:00Z 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                # In import files we can use the hash symbol at the end of a
42                # date string to avoid annoying automatic date transformation
43                # by Excel or Calc
44                input = input.strip('#')
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
74#: A dictionary of supported date formats.
75#:
76#: The following formats are supported:
77#:
78#: ``iso``
79#:    ISO format ``YYYY-MM-DD``
80#: ``le``
81#:    little endian with slashes: ``DD/MM/YYYY``
82#: ``de``
83#:    german date format: ``DD.MM.YYYY``
84#: ``us``
85#:    middle endian format common in the U.S.: ``MM/DD/YYYY``
86#:
87#: Furthermore we support for input widgets an additional year
88#: marker. Input date widgets with this marker provide also a year
89#: selector, handy for dates of birth etc.
90#:
91#: The year-supporting formats are similar to the basic versions above:
92#:
93#: ``iso-year``
94#:    ISO format ``YYYY-MM-DD``
95#: ``le-year``
96#:    little endian with slashes: ``DD/MM/YYYY``
97#: ``de-year``
98#:    german date format: ``DD.MM.YYYY``
99#: ``us-year``
100#:    middle endian format common in the U.S.: ``MM/DD/YYYY``
101#:   
102#: For date display widgets there is naturally no difference between a
103#: year and non-year setting (you can for instance use 'le' or 'le-year'
104#: with the same output).
105DATE_FORMATS = {
106    'iso': ('datepicker', '%Y-%m-%d'),
107    'le':  ('datepicker-le', '%d/%m/%Y'),
108    'de':  ('datepicker-de', '%d.%m.%Y'),
109    'us':  ('datepicker-us', '%m/%d/%Y'),
110    'iso-year': ('datepicker-year', '%Y-%m-%d'),
111    'le-year':  ('datepicker-le-year', '%d/%m/%Y'),
112    'de-year':  ('datepicker-de-year', '%d.%m.%Y'),
113    'us-year':  ('datepicker-us-year', '%m/%d/%Y'),
114    }
115def FriendlyDateWidget(format):
116    """Get a friendly date input widget for `format`.
117
118    This widget is suitable for edit and add forms.
119   
120    Valid `format` values are the keys of `DATE_FORMATS`
121    dict. Default is ``le`` (little endian; DD/MM/YYYY).
122
123    Friendly date widgets are rendered with a specialized CSS tag for
124    enabling JavaScript datepickers.
125    """
126    css_class, date_format = DATE_FORMATS.get(format, DATE_FORMATS['le'])
127    return CustomWidgetFactory(
128        FormattedDateWidget,
129        cssClass=css_class,
130        date_format=date_format)
131
132def FriendlyDateDisplayWidget(format):
133    """Get a friendly date display widget for `format`.
134
135    This widget is suitable for display forms.
136   
137    Valid `format` values are the keys of `DATE_FORMATS`
138    dict. Default is ``le`` (little endian; DD/MM/YYYY).
139
140    This widget is not rendered with a specialized CSS tag for
141    enabling JavaScript datepickers. `css_class` is ignored which means
142    there is nor difference between e.g. ``le`` and ``le-year``.`
143    """
144    css_class, date_format = DATE_FORMATS.get(format, DATE_FORMATS['le'])
145    return CustomWidgetFactory(
146        FormattedDateDisplayWidget,
147        date_format=date_format)
148
149def FriendlyDatetimeDisplayWidget(format):
150    """Get a friendly datetime display widget for `format`.
151
152    This widget is suitable for display forms.
153
154    Valid `format` values are the keys of `DATE_FORMATS`
155    dict. Default is ``le`` (little endian; DD/MM/YYYY %H:%M:%S).
156
157    This widget is not rendered with a specialized CSS tag for
158    enabling JavaScript datepickers. `css_class` is ignored which means
159    there is nor difference between e.g. ``le`` and ``le-year``.`
160    """
161    css_class, date_format = DATE_FORMATS.get(format, DATE_FORMATS['le'])
162    datetime_format = date_format + ' %H:%M:%S'
163    return CustomWidgetFactory(
164        FormattedDateDisplayWidget,
165        date_format=datetime_format)
Note: See TracBrowser for help on using the repository browser.