[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