[Zope3-checkins] CVS: Zope3/lib/python/Zope/App/Forms/Views/Browser - FormView.py:1.10 IForm.py:1.7 Widget.py:1.7
Martijn Faassen
m.faassen@vet.uu.nl
Wed, 4 Sep 2002 09:44:54 -0400
Update of /cvs-repository/Zope3/lib/python/Zope/App/Forms/Views/Browser
In directory cvs.zope.org:/tmp/cvs-serv31848/python/Zope/App/Forms/Views/Browser
Modified Files:
FormView.py IForm.py Widget.py
Log Message:
Refactored Forms (and Schema).
* A FormView now specifies a single schema explicitly as the 'schema'
(class) attribute. A schema is simply an interface with Field attributes
on it.
* The FormView code now uses the Schema package more for its own
implementation, instead of trying to reimplement things itself.
* got rid of the 'id' attribute for fields. Fields now already know what
name they have, because of the Interface package setting __name__.
Use getName() to get the field name.
=== Zope3/lib/python/Zope/App/Forms/Views/Browser/FormView.py 1.9 => 1.10 ===
--- Zope3/lib/python/Zope/App/Forms/Views/Browser/FormView.py:1.9 Wed Jul 24 06:53:48 2002
+++ Zope3/lib/python/Zope/App/Forms/Views/Browser/FormView.py Wed Sep 4 09:44:23 2002
@@ -14,12 +14,11 @@
"""
$Id$
"""
-from Interface.Implements import flattenInterfaces
from Schema.IField import IField
from Schema.Exceptions import StopValidation, ValidationError, \
ConversionError, ValidationErrorsAll, ConversionErrorsAll
-
-from Zope.Proxy.ContextWrapper import ContextWrapper
+from Schema import getFields, validateMappingAll
+#from Zope.Proxy.ContextWrapper import ContextWrapper
from Zope.ComponentArchitecture import getView
from Zope.Proxy.ProxyIntrospection import removeAllProxies
from Zope.Publisher.Browser.BrowserView import BrowserView
@@ -34,122 +33,82 @@
form = None
custom_widgets = None
+ schema = None
fields_order = None
def getFields(self):
'See Zope.App.Forms.Views.Browser.IForm.IReadForm'
- context = removeAllProxies(self.context)
- interfaces = context.__implements__
- if isinstance(interfaces, (tuple, list)):
- interfaces = flattenInterfaces(interfaces)
+ fields = getFields(self.schema)
+ fields_order = self.fields_order
+ if fields_order:
+ return [fields[name] for name in fields_order]
else:
- interfaces = (interfaces,)
- request = self.request
- fields = {}
- for interface in interfaces:
- for name in interface.names(1):
- attr = interface.getDescriptionFor(name)
- if IField.isImplementedBy(attr):
- # Give the field a context before adding, so they
- # know how to retrieve data.
- fields[name] = ContextWrapper(attr, self.context,
- name=name)
-
- if self.fields_order is None:
return fields.values()
-
- result = []
- for id in self.fields_order:
- result.append(fields[id])
- return result
-
-
- def getField(self, id):
+
+ def getField(self, name):
'See Zope.App.Forms.Views.Browser.IForm.IReadForm'
- # XXX This needs to be optimized!
- field = None
- for f in self.getFields():
- if f.id == id:
- field = f
- break
- if field is None:
- raise KeyError, 'Field id "%s" does not exist.' %id
+ field = self.schema.getDescriptionFor(name)
+ assert IField.isImplementedBy(field)
return field
-
- def getWidgetForFieldId(self, id):
+ def getWidgetForFieldName(self, name):
'See Zope.App.Forms.Views.Browser.IForm.IReadForm'
- field = self.getField(id)
- return self.getWidgetForField(field)
-
+ return self.getWidgetForField(self.getField(name))
def getWidgetForField(self, field):
'See Zope.App.Forms.Views.Browser.IForm.IReadForm'
- if self.custom_widgets is not None and \
- field.id in self.custom_widgets.keys():
- return self.custom_widgets[field.id](field, self.request)
+ name = field.getName()
+ if (self.custom_widgets is not None and
+ self.custom_widgets.has_key(name)):
+ return self.custom_widgets[name](field, self.request)
return getView(field, 'widget', self.request)
-
def renderField(self, field, useRequest=0):
'See Zope.App.Forms.Views.Browser.IForm.IReadForm'
widget = self.getWidgetForField(field)
value = None
if useRequest:
- value = self.request.form.get('field_' + field.id)
+ value = self.request.form.get('field_' + field.getName())
if value is None:
- value = getattr(self.context, field.id)
+ value = getattr(self.context, field.getName())
return widget.render(value)
-
def getAllRawFieldData(self):
"""Returns field data retrieved from request."""
request = self.request
data = {}
for field in self.getFields():
- raw_data = request.form.get('field_' + field.id)
- data[field] = raw_data
+ name = field.getName()
+ raw_data = request.form.get('field_' + name)
+ data[name] = raw_data
return data
-
- def convertAllFieldData(self, mapping):
+ def convertAllFieldData(self, raw_data):
"""Convert the raw data into valid objects."""
- data = {}
+ result = {}
errors = []
- for field in mapping:
- widget = self.getWidgetForField(field)
+ for name, value in raw_data.iteritems():
+ widget = self.getWidgetForFieldName(name)
try:
- data[field] = widget.convert(mapping[field])
+ result[name] = widget.convert(value)
except ConversionError, error:
- errors.append((field, error))
+ errors.append((name, error))
if errors:
raise ConversionErrorsAll, errors
-
- return data
-
- def validateAllFieldData(self, mapping):
+ return result
+
+ def validateAllFieldData(self, data):
"""Validate all the data."""
- errors = []
- for field in mapping:
- try:
- field.validate(mapping[field])
- except ValidationError, error:
- errors.append((field, error))
-
- if errors:
- raise ValidationErrorsAll, errors
+ validateMappingAll(self.schema, data)
-
- def storeAllDataInContext(self, mapping):
+ def storeAllDataInContext(self, data):
"""Store the data back into the context object."""
context = removeAllProxies(self.context)
- for field in mapping:
- value = mapping[field]
- if value != getattr(context, field.id):
- setattr(context, field.id, value)
-
+ for name, value in data.iteritems():
+ if value != getattr(context, name):
+ setattr(context, name, value)
def saveValuesInContext(self):
'See Zope.App.Forms.Views.Browser.IForm.IWriteForm'
@@ -157,7 +116,6 @@
data = self.convertAllFieldData(data)
self.validateAllFieldData(data)
self.storeAllDataInContext(data)
-
def action(self):
'See Zope.App.Forms.Views.Browser.IForm.IWriteForm'
=== Zope3/lib/python/Zope/App/Forms/Views/Browser/IForm.py 1.6 => 1.7 ===
--- Zope3/lib/python/Zope/App/Forms/Views/Browser/IForm.py:1.6 Wed Jul 24 06:53:48 2002
+++ Zope3/lib/python/Zope/App/Forms/Views/Browser/IForm.py Wed Sep 4 09:44:23 2002
@@ -24,6 +24,9 @@
form = Attribute(
"""The form template. Usually a Page Template.""")
+ schema = Attribute(
+ """The schema this form should be constructed from.""")
+
custom_widgets = Attribute(
"""A dictionary that holds custom widgets for various fields.""")
@@ -39,15 +42,15 @@
def getFields():
"""Get all the fields that need input from the content object."""
- def getField(id):
- """Get a field by id from the content object schemas."""
+ def getField(name):
+ """Get a field by name from the content object schemas."""
- def getWidgetForFieldId(id):
- """Lookup the widget of the field having id."""
+ def getWidgetForFieldName(name):
+ """Lookup the widget of the field by name."""
def getWidgetForField(field):
"""Return the correct widget instance for a field. This method
- consildates the custom_widgets attribute """
+ consults the custom_widgets attribute """
def renderField(field):
"""Render a field using the widgets."""
=== Zope3/lib/python/Zope/App/Forms/Views/Browser/Widget.py 1.6 => 1.7 ===
--- Zope3/lib/python/Zope/App/Forms/Views/Browser/Widget.py:1.6 Wed Jul 24 06:53:48 2002
+++ Zope3/lib/python/Zope/App/Forms/Views/Browser/Widget.py Wed Sep 4 09:44:23 2002
@@ -49,7 +49,7 @@
'See Zope.App.Forms.Views.Browser.IBrowserWidget.IBrowserWidget'
return renderElement(self.getValue('tag'),
type = self.getValue('type'),
- name = self.context.id,
+ name = self.context.getName(),
value = value,
cssClass = self.getValue('cssClass'),
extra = self.getValue('extra'))
@@ -58,7 +58,7 @@
'See Zope.App.Forms.Views.Browser.IBrowserWidget.IBrowserWidget'
return renderElement(self.getValue('tag'),
type = 'hidden',
- name = self.context.id,
+ name = self.context.getName(),
value = value,
cssClass = self.getValue('cssClass'),
extra = self.getValue('extra'))
@@ -78,14 +78,14 @@
if value:
return renderElement(self.getValue('tag'),
type = self.getValue('type'),
- name = self.context.id,
+ name = self.context.getName(),
checked = None,
cssClass = self.getValue('cssClass'),
extra = self.getValue('extra'))
else:
return renderElement(self.getValue('tag'),
type = self.getValue('type'),
- name = self.context.id,
+ name = self.context.getName(),
cssClass = self.getValue('cssClass'),
size = self.getValue('displayWidth'),
extra = self.getValue('extra'))
@@ -106,7 +106,7 @@
if displayMaxWidth > 0:
return renderElement(self.getValue('tag'),
type = self.getValue('type'),
- name = self.context.id,
+ name = self.context.getName(),
value = value,
cssClass = self.getValue('cssClass'),
size = self.getValue('displayWidth'),
@@ -115,7 +115,7 @@
else:
return renderElement(self.getValue('tag'),
type = self.getValue('type'),
- name = self.context.id,
+ name = self.context.getName(),
value = value,
cssClass = self.getValue('cssClass'),
size = self.getValue('displayWidth'),
@@ -135,7 +135,7 @@
def render(self, value):
'See Zope.App.Forms.Views.Browser.IBrowserWidget.IBrowserWidget'
return renderElement("textarea",
- name=self.context.id,
+ name=self.context.getName(),
cssClass=self.getValue('cssClass'),
cols=self.getValue('width'),
rows=self.getValue('height'),
@@ -159,7 +159,7 @@
if displayMaxWidth > 0:
return renderElement(self.getValue('tag'),
type = self.getValue('type'),
- name = self.context.id,
+ name = self.context.getName(),
cssClass = self.getValue('cssClass'),
size = self.getValue('displayWidth'),
maxlength = displayMaxWidth,
@@ -167,7 +167,7 @@
else:
return renderElement(self.getValue('tag'),
type = self.getValue('type'),
- name = self.context.id,
+ name = self.context.getName(),
cssClass = self.getValue('cssClass'),
size = self.getValue('displayWidth'),
extra = self.getValue('extra'))
@@ -185,7 +185,7 @@
firstItem = 0
def renderItems(self, value):
- name = self.context.id
+ name = self.context.getName()
# get items
items = self.context.items
if callable(items):
@@ -236,7 +236,7 @@
'See Zope.App.Forms.Views.Browser.IBrowserWidget.IBrowserWidget'
renderedItems = self.renderItems(value)
return renderElement('select',
- name=self.context.id,
+ name=self.context.getName(),
cssClass=self.getValue('cssClass'),
size=self.getValue('size'),
contents="\n".join(renderedItems),
@@ -294,7 +294,7 @@
if not isinstance(value, ListTypes):
value = [value]
- name = self.context.id
+ name = self.context.getName()
items = self.context.items
if callable(items):
items = items()
@@ -333,7 +333,7 @@
'See Zope.App.Forms.Views.Browser.IBrowserWidget.IBrowserWidget'
rendered_items = self.renderItems(value)
return renderElement('select',
- name=self.context.id,
+ name=self.context.getName(),
multiple=None,
cssClass=self.getValue('cssClass'),
size=self.getValue('size'),