[Zope3-checkins] CVS: Zope3/src/zope/app/form - utility.py:1.14

Steve Alexander steve@cat-box.net
Wed, 5 Mar 2003 08:13:42 -0500


Update of /cvs-repository/Zope3/src/zope/app/form
In directory cvs.zope.org:/tmp/cvs-serv5384/src/zope/app/form

Modified Files:
	utility.py 
Log Message:
Added another useful option to setUpWidget.
Added some clarifying comments, which will be useful for when I refactor
Fields and Widgets to take into account missing values.


=== Zope3/src/zope/app/form/utility.py 1.13 => 1.14 ===
--- Zope3/src/zope/app/form/utility.py:1.13	Fri Feb 21 12:52:18 2003
+++ Zope3/src/zope/app/form/utility.py	Wed Mar  5 08:13:40 2003
@@ -50,7 +50,7 @@
     return fields
 
 def setUpWidget(view, name, field, value=None, prefix=None,
-                force=0, vname=None):
+                force=False, vname=None, context=None):
     """Set up a single view widget
 
     The widget will be an attribute of the view. If there is already
@@ -63,9 +63,12 @@
     # Has a (custom) widget already been defined?
     widget = getattr(view, name, None)
 
+    if context is None:
+        context = view.context
+
     if widget is None:
         # There isn't already a widget, create one
-        field = field.bind(view.context)
+        field = field.bind(context)
         if vname is None:
             vname = getDefaultViewName(field, view.request)
         widget = getView(field, vname, view.request)
@@ -76,7 +79,7 @@
         if IViewFactory.isImplementedBy(widget):
             # This is a view factory, probably a custom widget.
             # Try to make it into a widget.
-            field = field.bind(view.context)
+            field = field.bind(context)
             widget = widget(field, view.request)
             if IWidget.isImplementedBy(widget):
                 # Yee ha! We have a widget now, save it
@@ -91,22 +94,32 @@
     if prefix:
         widget.setPrefix(prefix)
 
+    # XXX
+    # Only set data if the widget doesn't have any itself already from the
+    # request. This is a problem for something like a checkbox, where it
+    # always claims to have data, becuase when there is no name in the request
+    # for it, its value is False.
+    # This is only a problem when force is False.
+    #
+    # It took me a while to work out what 'force' means in all these methods.
+    # Perhaps it should be renamed 'preserveExistingData', and have the
+    # opposite meaning.
     if value is not None and (force or not widget.haveData()):
         widget.setData(value)
 
 
-def setUpWidgets(view, schema, prefix=None, force=0,
-                 initial={}, names=None):
+def setUpWidgets(view, schema, prefix=None, force=False,
+                 initial={}, names=None, context=None):
     """Set up widgets for the fields defined by a schema
 
     """
     for (name, field) in _fieldlist(names, schema):
         setUpWidget(view, name, field, initial.get(name),
-                    prefix=prefix, force=force)
+                    prefix=prefix, force=force, context=context)
 
 
-def setUpEditWidgets(view, schema, content=None, prefix=None, force=0,
-                     names=None):
+def setUpEditWidgets(view, schema, content=None, prefix=None, force=False,
+                     names=None, context=None):
     """Set up widgets for the fields defined by a schema
 
     Initial data is provided by content object attributes.
@@ -114,7 +127,10 @@
     attribute, or if the named attribute value is None.
     """
     if content is None:
-        content = view.context
+        if context is None:
+            content = view.context
+        else:
+            content = context
 
     for name, field in _fieldlist(names, schema):
         if field.readonly:
@@ -130,7 +146,7 @@
             value = None
 
         setUpWidget(view, name, field, value,
-                    prefix = prefix, force = force, vname = vname)
+                    prefix=prefix, force=force, vname=vname, context=context)
 
 def haveWidgetsData(view, schema, names=None):
     """Check if we have any user-entered data defined by a schema
@@ -144,7 +160,8 @@
 
     return False
 
-def getWidgetsData(view, schema, strict=True, names=None, set_missing=True):
+def getWidgetsData(view, schema, strict=True, names=None, set_missing=True,
+                   do_not_raise=False):
     """Collect the user-entered data defined by a schema
 
     Data is collected from view widgets. For every field in the
@@ -166,7 +183,12 @@
     WidgetsError is raised.  If it's not required and it's empty, its
     value will be the appropriate missing value.  Right now this is
     hardcoded as None, but it should be changed so the field can
-    provide it as an empty string."""
+    provide it as an empty string.
+
+    do_not_raise is used if a call to getWidgetsData raises an exception,
+    and you want to make use of the data that *is* available in your
+    error-handler.
+    """
 
     result = {}
     errors = []
@@ -186,7 +208,7 @@
             elif set_missing:
                 result[name] = None # XXX field.missing_value
 
-    if errors:
+    if errors and not do_not_raise:
         raise WidgetsError(*errors)
 
     return result