[Zope3-checkins] CVS: Zope3/src/zope/app/form - utility.py:1.25.4.3 widget.py:1.10.4.5

Garrett Smith garrett at mojave-corp.com
Mon Feb 16 12:40:57 EST 2004


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

Modified Files:
      Tag: ozzope-widgets-branch
	utility.py widget.py 
Log Message:

Continued refactoring of widgets machinery - still work in progress.


=== Zope3/src/zope/app/form/utility.py 1.25.4.2 => 1.25.4.3 ===
--- Zope3/src/zope/app/form/utility.py:1.25.4.2	Sun Feb  8 23:31:46 2004
+++ Zope3/src/zope/app/form/utility.py	Mon Feb 16 12:40:26 2004
@@ -61,9 +61,19 @@
     field = field.bind(context)
     return zapi.getViewProviding(field, viewType, request)        
 
-
+def _widgetHasStickyValue(widget):
+    """Returns True if the widget has a sticky value.
+    
+    A sticky value is input from the user that should not be overridden
+    by an object's current field value. E.g. a user may enter an invalid
+    postal code, submit the form, and receive a validation error - the postal
+    code should be treated as 'sticky' until the user successfully updates
+    the object.
+    """
+    return IEditWidget.isImplementedBy(widget) and widget.hasInput()
+    
 def setUpWidget(view, name, field, viewType, value=None, prefix=None,
-                force=False, context=None):
+                ignoreStickyValue=False, context=None):
     """Sets up a single view widget.
 
     The widget will be an attribute of the view. If there is already
@@ -82,100 +92,89 @@
     if widget is None:
         # does not exist - create it
         widget = _createWidget(context, field, viewType, view.request)
+        setattr(view, widgetName, widget)
     elif IViewFactory.isImplementedBy(widget):
         # exists, but is actually a factory - use it to create the widget
         widget = widget(field.bind(context), view.request)
+        setattr(view, widgetName, widget)
         
     # widget must implement IWidget
     if not IWidget.isImplementedBy(widget):
         raise TypeError(
-            "Invalid attribute %s in view %s - expected an object that "
-            "implements IWidget, got %r" 
-            % (widgetName, view.__class__.__name__, widget))
-    
-    # ensure the widget is an attribute of the view
-    if not hasattr(view, widgetName):
-        setattr(view, widgetName, widget)
+            "Unable to configure a widget for %s - attribute %s does not "
+            "implement IWidget" % (name, widgetName))
     
     if prefix:
         widget.setPrefix(prefix)
         
-    if not widget.hasInput() or force:
+    if ignoreStickyValue or not _widgetHasStickyValue(widget):
         widget.setRenderedValue(value)
 
 
-def setUpWidgets(view, schema, viewType, prefix=None, force=False,
+def setUpWidgets(view, schema, viewType, prefix=None, ignoreStickyValue=False,
                  initial={}, names=None, context=None):
     """Sets up widgets for the fields defined by a schema.
     
-    view is the view to which the widgets will be added. 
-    
-    If view has an attribute named <field_name>_widget, where field_name is
-    the name of a schema field, that attribute must either be a widget
-    (IWidget) or a view factory (IViewFactory) that creates a widget. If the 
-    attribute value is a widget, it is used as is. If the attribute value
-    is a view factory, it is used to create a widget, which is set as the 
-    new view attribute.
-    
-    schema is an interface that contains the fields for which widget are
-    setup.
+    view is the view that will be configured with widgets. 
+        
+    schema is an interface containing the fields that widgets will be
+    created for.
     
     prefix is a string that is appended to the widget names in the generated
     HTML. This can be used to differentiate widgets for different schemas.
     
-    force - XXX OZ rename?
-    
-    initial - XXX OZ initial values to use
+    ignoreStickyValue is a flag that, when True, will cause widget sticky
+    values to be replaced with the context field value or a value specified
+    in initial.
+    
+    initial is a mapping of field names to initial values.
+    
+    names is an optional iterable that provides an ordered list of field
+    names to use. If names is None, the list of fields will be defined by
+    the schema.
     
-    names - XXX OZ the field names?
-    
-    context - the context, or view's context by default?
+    context provides an alternative context that will be used instead of the
+    view context.
     """
     for (name, field) in _fieldlist(names, schema):
         setUpWidget(view, name, field, viewType, value=initial.get(name),
-                    prefix=prefix, force=force, context=context)
+                    prefix=prefix, ignoreStickyValue=ignoreStickyValue, 
+                    context=context)
 
-def setUpEditWidgets(view, schema, content=None, prefix=None, force=False,
+def setUpEditWidgets(view, schema, prefix=None, ignoreStickyValue=False,
                      names=None, context=None):
     """Sets up widgets for an edit form.
     
     See setUpWidgets for details on this method's arguments.
     """
-    _setUpWidgets(view, schema, content, prefix, force,
-                  names, context, IDisplayWidget, IEditWidget)
+    _setUpFormWidgets(view, schema, prefix, ignoreStickyValue, names, context, 
+                      IDisplayWidget, IEditWidget)
 
-def setUpDisplayWidgets(view, schema, content=None, prefix=None, force=False,
+def setUpDisplayWidgets(view, schema, prefix=None, ignoreStickyValue=False,
                         names=None, context=None):
     """Sets up widgets for a display (read-only) form.
     
     See setUpWidgets for details on this method's arguments.
     """
-    _setUpWidgets(view, schema, content, prefix, force,
-                  names, context, IDisplayWidget, IDisplayWidget)
-
-def _setUpWidgets(view, schema, content, prefix, force,
-                  names, context, displayType, editType):
-    """A helper function used by setUpDisplayWidget and setUpEditWidget."""    
-    if content is None:
-        if context is None:
-            content = view.context
-        else:
-            content = context
+    _setUpFormWidgets(view, schema, prefix, ignoreStickyValue, names, context, 
+                      IDisplayWidget, IDisplayWidget)
 
+def _setUpFormWidgets(view, schema, prefix, ignoreStickyValue, names, context, 
+                      displayType, editType):
+    """A helper function used by setUpDisplayWidget and setUpEditWidget."""
+    if context is None:
+        context = view.context
     for name, field in _fieldlist(names, schema):
         if field.readonly:
             viewType = displayType
         else:
             viewType = editType
-
         try:
-            value = field.get(content)
+            value = field.get(context)
         except AttributeError, v:
-            if v.__class__ != AttributeError:
-                raise
             value = None
-
-        setUpWidget(view, name, field, viewType, value, prefix, force, context)
+        setUpWidget(view, name, field, viewType, value, prefix,
+                    ignoreStickyValue, context)
 
 def viewHasInput(view, schema, names=None):
     """Check if we have any user-entered data defined by a schema.
@@ -188,86 +187,73 @@
             return True
     return False
 
-def applyWidgetsChanges(view, content, schema, strict=True,
-        names=None, set_missing=True, do_not_raise=False,
-        exclude_readonly=False):
-    """Apply changes in widgets to the object.
+def applyWidgetsChanges(view, schema, names=None, context=None):
+    """Apply changes in widgets to the object."""
     
-    XXX this needs to be thoroughly documented.
-    """
     errors = []
     changed = False
+    if context is None:
+        context = view.context
+    
     for name, field in _fieldlist(names, schema):
         widget = getattr(view, name + '_widget')
-        if exclude_readonly and field.readonly:
-            continue
-        if widget.hasInput():
+        if IEditWidget.isImplementedBy(widget) and widget.hasInput():
             try:
-                changed = widget.applyChanges(content) or changed
+                changed = widget.applyChanges(context) or changed
             except InputErrors, v:
                 errors.append(v)
-
-    if errors and not do_not_raise:
+    if errors:
         raise WidgetsError(*errors)
-
+        
     return changed
 
-def getWidgetsData(view, schema, strict=True, names=None, set_missing=True,
-                   do_not_raise=False, exclude_readonly=False):
-    """Collect the user-entered data defined by a schema
-
-    Data is collected from view widgets. For every field in the
-    schema, we look for a view of the same name and get it's data.
-
-    The data are returned in a mapping from field name to value.
-
-    If the strict argument is true, then all of the data defined by
-    the schema will be returned. If some required data are missing
-    from the input, an error will be raised.
-
-    If set_missing is true and the widget has no data, then the
-    field's value is set to its missing value.  Otherwise, a widget
-    with no data is ignored. (However, if that field is required and
-    strict is true, an error will be raised.)
-
-    E.g., a typical text line widget should have a min_length of 1,
-    and if it is required, it has got to have something in, otherwise
-    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.
-
-    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.
-
-    Normally, readonly fields are included. To exclude readonly fields,
-    provide a exclude_readonly keyword argument with a true value.
-
+def getWidgetsData(view, schema, names=None):
+    """Returnd user entered data for a set of schema fields.
+    
+    The return value is a map of field names to user entered data.
+    
+    view is the view containing the widgets. schema is the schema that
+    defines the widget fields. An optional names argument can be provided
+    to specify an alternate list of field values to return. If names is
+    not specified, or is None, getWidgetsData will attempt to return values
+    for all of the fields in the schema.
+    
+    A requested field value may be omitted from the result for one of two
+    reasons:
+        
+        - The field is read only, in which case its widget will not have
+          user input.
+          
+        - The field is editable and not required but its widget does not 
+          contain user input.
+    
+    If a field is required and its widget does not have input, getWidgetsData
+    raises an error.
+    
+    A widget may raise a validation error if it cannot return a value that
+    satisfies its field's contraints.
+    
+    Errors, if any, are collected for all fields and reraised as a single
+    WidgetsError.
     """
-
     result = {}
     errors = []
-
+    
     for name, field in _fieldlist(names, schema):
         widget = getattr(view, name + '_widget')
-        if exclude_readonly and widget.context.readonly:
-            continue
-        if widget.hasInput():
-            try:
-                result[name] = widget.getInputValue()
-            except InputErrors, v:
-                errors.append(v)
-        elif strict and field.required:
-            errors.append(MissingInputError(name, widget.title,
-                                            'the field is required')
-                          )
-        elif set_missing:
-            result[name] = field.missing_value
-
-    if errors and not do_not_raise:
+        if IEditWidget.isImplementedBy(widget):
+            if widget.hasInput():
+                try:
+                    result[name] = widget.getInputValue()
+                except InputErrors, v:
+                    errors.append(v)
+            elif field.required:
+                errors.append(MissingInputError(
+                    name, widget.title, 'the field is required'))
+            
+    if errors:
         raise WidgetsError(*errors)
-
+        
     return result
 
 def getWidgetsDataForContent(view, schema, content=None, strict=True,
@@ -291,7 +277,6 @@
     the schema will be set, at least for required fields. If some data
     for required fields are missing from the input, an error will be
     raised.
-
     """
     data = getWidgetsData(view, schema, strict, names)
 


=== Zope3/src/zope/app/form/widget.py 1.10.4.4 => 1.10.4.5 ===
--- Zope3/src/zope/app/form/widget.py:1.10.4.4	Sun Feb  8 23:29:05 2004
+++ Zope3/src/zope/app/form/widget.py	Mon Feb 16 12:40:26 2004
@@ -72,6 +72,8 @@
     def setRenderedValue(self, value):
         self._data = value
         
+    def getRenderedValue(self):
+        return self._data
 
 class CustomWidgetFactory:
     """Custom Widget Factory.




More information about the Zope3-Checkins mailing list