Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Pylons/deform
Browse files Browse the repository at this point in the history
  • Loading branch information
dnouri committed Mar 30, 2012
2 parents 22d958e + 60683a8 commit 30a6e6a
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 37 deletions.
2 changes: 2 additions & 0 deletions CHANGES.txt
Expand Up @@ -10,6 +10,8 @@ Next release

- Modified Russian translation thanks to aleksandr.rakov

- Date(Time)Widget supports now options to configure it, thx to gaston tjebbes, kiorky

0.9.4 (2012-02-14)
------------------

Expand Down
4 changes: 2 additions & 2 deletions deform/templates/dateinput.pt
@@ -1,15 +1,15 @@
<span tal:omit-tag="">
<input type="date"
name="${field.name}"
value="${cstruct}"
value="${cstruct}"
tal:attributes="size field.widget.size;
class field.widget.css_class"
id="${field.oid}"/>
<script type="text/javascript">
deform.addCallback(
'${field.oid}',
function(oid) {
$('#' + oid).datepicker({dateFormat: 'yy-mm-dd'});
$('#' + oid).datepicker(${options});
}
);
</script>
Expand Down
37 changes: 30 additions & 7 deletions deform/tests/test_widget.py
Expand Up @@ -289,11 +289,34 @@ def test_deserialize_emptystring(self):
result = widget.deserialize(field, '')
self.assertEqual(result, null)

def test_options(self):
widget = self._makeOne()
widget.options['dummy'] = 'dummyvalue'
self.assertTrue(('dummy', 'dummyvalue') in widget.options.items())

def test_options_changed_and_default(self):
widget2 = self._makeOne()
widget = self._makeOne(options={'dateFormat': 'foo'})
self.assertEquals(widget.options['dateFormat'], 'foo')
self.assertEquals(widget2.options['dateFormat'], 'yy-mm-dd')


class TestDateTimeInputWidget(TestDateInputWidget):
def _makeOne(self, **kw):
from deform.widget import DateTimeInputWidget
return DateTimeInputWidget(**kw)

def test_options(self):
widget = self._makeOne()
widget.options['dummy'] = 'dummyvalue'
self.assertTrue(('dummy', 'dummyvalue') in widget.options.items())

def test_options_changed_and_default(self):
widget2 = self._makeOne()
widget = self._makeOne(options={'dateFormat': 'foo'})
self.assertEquals(widget.options['dateFormat'], 'foo')
self.assertEquals(widget2.options['dateFormat'], 'yy-mm-dd')

def test_serialize_with_timezone(self):
widget = self._makeOne()
renderer = DummyRenderer()
Expand Down Expand Up @@ -329,7 +352,7 @@ class TestHiddenWidget(unittest.TestCase):
def _makeOne(self, **kw):
from deform.widget import HiddenWidget
return HiddenWidget(**kw)

def test_serialize_null(self):
from colander import null
widget = self._makeOne()
Expand Down Expand Up @@ -359,7 +382,7 @@ def test_serialize_not_null(self):
self.assertEqual(renderer.template, widget.template)
self.assertEqual(renderer.kw['field'], field)
self.assertEqual(renderer.kw['cstruct'], cstruct)

def test_deserialize(self):
widget = self._makeOne()
field = DummyField()
Expand Down Expand Up @@ -969,7 +992,7 @@ def test_deserialize_emptyfields(self):
schema = DummySchema()
field = DummyField(schema, None)
widget = self._makeOne()
result = widget.deserialize(field,
result = widget.deserialize(field,
{'year':'\t', 'month':'', 'day':''})
self.assertEqual(result, null)

Expand Down Expand Up @@ -1172,7 +1195,7 @@ def test_serialize_null_min_one(self):
self.assertEqual(renderer.kw['field'], field)
self.assertEqual(renderer.kw['cstruct'], [null])
self.assertEqual(renderer.template, widget.template)

def test_serialize_add_subitem_value(self):
from colander import null
renderer = DummyRenderer('abc')
Expand Down Expand Up @@ -1421,7 +1444,7 @@ def test_handle_error_outermost_has_msg(self):
field = DummyField()
widget.handle_error(field, error)
self.assertEqual(field.error, error)

def test_handle_error_children_have_msgs(self):
widget = self._makeOne()
error = DummyInvalid()
Expand Down Expand Up @@ -1525,7 +1548,7 @@ def test_handle_error_outermost_has_msg(self):
field = DummyField()
widget.handle_error(field, error)
self.assertEqual(field.error, error)

def test_handle_error_children_have_msgs(self):
widget = self._makeOne()
error = DummyInvalid()
Expand Down Expand Up @@ -1568,7 +1591,7 @@ def test_set_css_resources(self):
def test___call___no_requirement(self):
reg = self._makeOne()
self.assertRaises(ValueError, reg.__call__, ( ('abc', 'def'), ))

def test___call___no_version(self):
reg = self._makeOne()
reg.registry = {'abc':{'123':{'js':(1,2)}}}
Expand Down
60 changes: 32 additions & 28 deletions deform/widget.py
@@ -1,6 +1,6 @@
import csv
import random
import json
import json

from colander import Invalid
from colander import null
Expand Down Expand Up @@ -63,7 +63,7 @@ class Widget(object):
The name of the CSS class attached to various tags in the form
renderering indicating an error condition for the field
associated with this widget. Default: ``error``.
css_class
The name of the CSS class attached to various tags in
the form renderering specifying a new class for the field
Expand Down Expand Up @@ -328,7 +328,7 @@ def deserialize(self, field, pstruct):

class DateInputWidget(Widget):
"""
Renders a JQuery UI date picker widget
(http://jqueryui.com/demos/datepicker/). Most useful when the
schema node is a ``colander.Date`` object.
Expand All @@ -344,6 +344,9 @@ class DateInputWidget(Widget):
The template name used to render the widget. Default:
``dateinput``.
options
Options for configuring the widget (eg: date format)
readonly_template
The template name used to render the widget in read-only mode.
Default: ``readonly/textinput``.
Expand All @@ -352,12 +355,21 @@ class DateInputWidget(Widget):
readonly_template = 'readonly/textinput'
size = None
requirements = ( ('jqueryui', None), )
default_options = (('dateFormat', 'yy-mm-dd'),)


def __init__(self, *args, **kwargs):
self.options = dict(self.default_options)
Widget.__init__(self, *args, **kwargs)

def serialize(self, field, cstruct, readonly=False):
if cstruct in (null, None):
cstruct = ''
template = readonly and self.readonly_template or self.template
return field.renderer(template, field=field, cstruct=cstruct)
return field.renderer(template,
field=field,
cstruct=cstruct,
options=self.options)

def deserialize(self, field, pstruct):
if pstruct in ('', null):
Expand Down Expand Up @@ -392,36 +404,28 @@ class DateTimeInputWidget(DateInputWidget):
readonly_template = 'readonly/textinput'
size = None
requirements = ( ('jqueryui', None), ('datetimepicker', None), )
option_defaults = {'dateFormat': 'yy-mm-dd',
'timeFormat': 'hh:mm:ss',
'separator': ' '}
options = {}

def _options(self):
options = self.option_defaults.copy()
options.update(self.options)
return options
default_options = (DateInputWidget.default_options +
(('timeFormat', 'hh:mm:ss'),
('separator', ' ')))

def serialize(self, field, cstruct, readonly=False):
if cstruct in (null, None):
cstruct = ''
template = readonly and self.readonly_template or self.template
options = self._options()
if len(cstruct) == 25: # strip timezone if it's there
cstruct = cstruct[:-6]
cstruct = options['separator'].join(cstruct.split('T'))
cstruct = self.options['separator'].join(cstruct.split('T'))
return field.renderer(
template,
field=field,
cstruct=cstruct,
options=json.dumps(self._options()),
options=json.dumps(self.options),
)

def deserialize(self, field, pstruct):
if pstruct in ('', null):
return null
options = self._options()
return pstruct.replace(options['separator'], 'T')
return pstruct.replace(self.options['separator'], 'T')

class TextAreaWidget(TextInputWidget):
"""
Expand Down Expand Up @@ -466,7 +470,7 @@ class RichTextWidget(TextInputWidget):
To use this widget the :term:`TinyMCE Editor` library must be
provided in the page where the widget is rendered. A version of
:term:`TinyMCE Editor` is included in deform's static directory.
**Attributes/Arguments**
Expand All @@ -490,7 +494,7 @@ class RichTextWidget(TextInputWidget):
The template name used to render the widget. Default:
``richtext``.
skin
skin
The skin for the WYSIWYG editor. Normally only needed if you
plan to reuse a TinyMCE js from another framework that
defined a skin.
Expand Down Expand Up @@ -869,7 +873,7 @@ def serialize(self, field, cstruct, readonly=False):

def deserialize(self, field, pstruct):
error = None

result = {}

if pstruct is null:
Expand All @@ -878,7 +882,7 @@ def deserialize(self, field, pstruct):
for num, subfield in enumerate(field.children):
name = subfield.name
subval = pstruct.get(name, null)

try:
result[name] = subfield.deserialize(subval)
except Invalid as e:
Expand Down Expand Up @@ -1227,7 +1231,7 @@ def deserialize(self, field, pstruct):
year = pstruct['year'].strip()
month = pstruct['month'].strip()
day = pstruct['day'].strip()

if (not year and not month and not day):
return null

Expand All @@ -1245,7 +1249,7 @@ class TextAreaCSVWidget(Widget):
Widget used for a sequence of tuples of scalars; allows for
editing CSV within a text area. Used with a schema node which is
a sequence of tuples.
**Attributes/Arguments**
cols
Expand Down Expand Up @@ -1285,7 +1289,7 @@ def serialize(self, field, cstruct, readonly=False):
else:
template = self.template
return field.renderer(template, field=field, cstruct=textrows)

def deserialize(self, field, pstruct):
if pstruct is null:
return null
Expand Down Expand Up @@ -1315,7 +1319,7 @@ class TextInputCSVWidget(Widget):
Widget used for a tuple of scalars; allows for editing a single
CSV line within a text input. Used with a schema node which is a
tuple composed entirely of scalar values (integers, strings, etc).
**Attributes/Arguments**
template
Expand Down Expand Up @@ -1350,7 +1354,7 @@ def serialize(self, field, cstruct, readonly=False):
else:
template = self.template
return field.renderer(template, field=field, cstruct=textrow)

def deserialize(self, field, pstruct):
if pstruct is null:
return null
Expand Down Expand Up @@ -1442,7 +1446,7 @@ def __call__(self, requirements):
result[thing].append(source)
return result


default_resources = {
'jquery': {
None:{
Expand Down

0 comments on commit 30a6e6a

Please sign in to comment.