Skip to content
Browse files

- The constructor of ``deform.Field`` objects (and thus

  ``deform.Form`` objects) now accept arbitrary keyword arguments,
  each of which is attached to the field or form object being
  constructed, as well as being attached to its descendant fields
  recursively.

- The form object's template now respects the ``css_class`` argument /
  attribute of the form node.
  • Loading branch information...
1 parent 0645cd0 commit c201b508bcac79e00a1a88a4cb3e542cf8715aa2 @mcdonc mcdonc committed Aug 31, 2010
Showing with 123 additions and 61 deletions.
  1. +9 −0 CHANGES.txt
  2. +85 −59 deform/field.py
  3. +1 −0 deform/form.py
  4. +2 −2 deform/templates/form.pt
  5. +15 −0 deform/tests/test_field.py
  6. +11 −0 deform/tests/test_form.py
View
9 CHANGES.txt
@@ -36,6 +36,15 @@ Features
For more information, see "Changing the Default Widget Associated
With a Field" in the documentation.
+- The constructor of ``deform.Field`` objects (and thus
+ ``deform.Form`` objects) now accept arbitrary keyword arguments,
+ each of which is attached to the field or form object being
+ constructed, as well as being attached to its descendant fields
+ recursively.
+
+- The form object's template now respects the ``css_class`` argument /
+ attribute of the form node.
+
Requirements
~~~~~~~~~~~~
View
144 deform/field.py
@@ -20,76 +20,100 @@ class Field(object):
those widget still only need to be constructed once instead of on
each request.
- All field objects have the following attributes:
+ *Attributes*
- schema
- The schema node associated with this field.
+ schema
+ The schema node associated with this field.
- widget
- The widget associated with this field.
+ widget
+ The widget associated with this field.
- order
- An integer indicating the relative order of this field's
- construction to its children and parents.
+ order
+ An integer indicating the relative order of this field's
+ construction to its children and parents.
- oid
- A string incorporating the ``order`` attribute that can be
- used as a unique identifier in HTML code (often for ``id``
- attributes of field-related elements). An example oid is
- ``deformField0``.
+ oid
+ A string incorporating the ``order`` attribute that can be
+ used as a unique identifier in HTML code (often for ``id``
+ attributes of field-related elements). An example oid is
+ ``deformField0``.
+
+ name
+ An alias for self.schema.name
+
+ title
+ An alias for self.schema.title
+
+ description
+ An alias for self.schema.description
+
+ required
+ An alias for self.schema.required
+
+ typ
+ An alias for self.schema.typ
+
+ children
+ Child fields of this field.
+
+ error
+ The exception raised by the last attempted validation of the
+ schema element associated with this field. By default, this
+ attribute is ``None``. If non-None, this attribute is usually
+ an instance of the exception class
+ :exc:`colander.Invalid`, which has a ``msg`` attribute
+ providing a human-readable validation error message.
+
+ errormsg
+ The ``msg`` attribute of the ``error`` attached to this field
+ or ``None`` if the ``error`` attached to this field is ``None``.
+
+ renderer
+ The template :term:`renderer` associated with the form. If a
+ renderer is not passed to the constructor, the default deform
+ renderer will be used (the :term:`default renderer`).
+
+ counter
+ ``None`` or an instance of ``itertools.counter`` which is used
+ to generate sequential order-related attributes such as
+ ``oid`` and ``order``.
+
+ resource_registry
+ The :term:`resource registry` associated with this field.
+
+ *Constructor Arguments*
+
+ ``renderer``, ``counter`` and ``resource_registry`` are accepted
+ as explicit keyword arguments to the :class:`deform.Field`.
+ These are also available as attribute values. ``renderer``, if
+ passed, is a template renderer as described in
+ :ref:`creating_a_renderer`. ``counter``, if passed, should be
+ an :attr:`itertools.counter` object (useful when rendering
+ multiple forms on the same page, see
+ `http://deformdemo.repoze.org/multiple_forms/
+ <http://deformdemo.repoze.org/multiple_forms/>`_.
+ ``resource_registry``, if passed should be a widget resource
+ registry (see also :ref:`get_widget_resources`).
+
+ If any of these values is ``None`` (their default), suitable
+ default values are used in their place.
+
+ The :class:`deform.Field` constructor also accepts *arbitrary*
+ keyword arguments. When an 'unknown' keyword argument is
+ passed, it is attached unmolested to the form field as an
+ attribute.
+
+ All keyword arguments (explicit and unknown) are also attached to
+ all *children* nodes of the field being constructed.
- name
- An alias for self.schema.name
-
- title
- An alias for self.schema.title
-
- description
- An alias for self.schema.description
-
- required
- An alias for self.schema.required
-
- typ
- An alias for self.schema.typ
-
- children
- Child fields of this field.
-
- error
- The exception raised by the last attempted validation of the
- schema element associated with this field. By default, this
- attribute is ``None``. If non-None, this attribute is usually
- an instance of the exception class
- :exc:`colander.Invalid`, which has a ``msg`` attribute
- providing a human-readable validation error message.
-
- errormsg
- The ``msg`` attribute of the ``error`` attached to this field
- or ``None`` if the ``error`` attached to this field is ``None``.
-
- renderer
- The template :term:`renderer` associated with the form. If a
- renderer is not passed to the constructor, the default deform
- renderer will be used (the :term:`default renderer`).
-
- counter
- ``None`` or an instance of ``itertools.counter`` which is used
- to generate sequential order-related attributes such as
- ``oid`` and ``order``.
-
- ``renderer`` and ``counter`` are accepted as keyword arguments to
- the :class:`deform.Field` constructor as well as being present as
- attribute values. If they are ``None`` (their default), suitable
- values are used in their place.
"""
error = None
default_renderer = template.default_renderer
default_resource_registry = widget.default_resource_registry
def __init__(self, schema, renderer=None, counter=None,
- resource_registry=None):
+ resource_registry=None, **kw):
self.counter = counter or itertools.count()
self.order = self.counter.next()
self.oid = 'deformField%s' % self.order
@@ -106,11 +130,13 @@ def __init__(self, schema, renderer=None, counter=None,
self.description = schema.description
self.required = schema.required
self.children = []
+ self.__dict__.update(kw)
for child in schema.children:
self.children.append(Field(child,
renderer=renderer,
counter=self.counter,
- resource_registry=resource_registry))
+ resource_registry=resource_registry,
+ **kw))
def __iter__(self):
""" Iterate over the children fields of this field. """
View
1 deform/form.py
@@ -76,6 +76,7 @@ class Form(field.Field):
keywords mean the same thing in the context of a Form as they do
in the context of a Field (a Form is just another kind of Field).
"""
+ css_class = 'wufoo'
def __init__(self, schema, action='', method='POST', buttons=(),
formid='deform', use_ajax=False, ajax_options='{}', **kw):
field.Field.__init__(self, schema, **kw)
View
4 deform/templates/form.pt
@@ -1,11 +1,11 @@
<form
id="${field.formid}"
action="${field.action}"
- class="wufoo"
method="${field.method}"
enctype="multipart/form-data"
accept-charset="utf-8"
- i18n:domain="deform">
+ i18n:domain="deform"
+ tal:attributes="class field.css_class">
<fieldset class="deformFormFieldset">
View
15 deform/tests/test_field.py
@@ -56,6 +56,21 @@ def test_ctor_with_resource_registry(self):
self.assertEqual(child_field.schema, node)
self.assertEqual(child_field.resource_registry, 'abc')
+ def test_ctor_with_unknown_kwargs(self):
+ from deform.field import Field
+ schema = DummySchema()
+ node = DummySchema()
+ schema.children = [node]
+ field = self._makeOne(schema, foo='foo', bar='bar')
+ self.assertEqual(len(field.children), 1)
+ child_field = field.children[0]
+ self.assertEqual(field.foo, 'foo')
+ self.assertEqual(field.bar, 'bar')
+ self.assertEqual(child_field.__class__, Field)
+ self.assertEqual(child_field.schema, node)
+ self.assertEqual(child_field.foo, 'foo')
+ self.assertEqual(child_field.bar, 'bar')
+
def test_set_default_renderer(self):
cls = self._getTargetClass()
old = cls.default_renderer
View
11 deform/tests/test_form.py
@@ -38,6 +38,17 @@ def test_ctor_buttons_notstrings(self):
button = form.buttons[0]
self.assertEqual(button, None)
+ def test_ctor_passes_unknown_kwargs(self):
+ schema = DummySchema()
+ schema.children = [DummySchema()]
+ form = self._makeOne(schema, a='a', b='b')
+ self.assertEqual(form.schema, schema)
+ self.assertEqual(form.a, 'a')
+ self.assertEqual(form.b, 'b')
+ child = form.children[0]
+ self.assertEqual(child.a, 'a')
+ self.assertEqual(child.b, 'b')
+
class TestButton(unittest.TestCase):
def _makeOne(self, **kw):
from deform.form import Button

0 comments on commit c201b50

Please sign in to comment.
Something went wrong with that request. Please try again.