[Zope3-checkins] CVS: Zope3/src/zope/app/browser/form - editview.py:1.28.2.1 vocabularywidget.py:1.46.10.1 widget.py:1.43.2.1
Garrett Smith
garrett@mojave-corp.com
Tue, 22 Jul 2003 09:01:39 -0400
Update of /cvs-repository/Zope3/src/zope/app/browser/form
In directory cvs.zope.org:/tmp/cvs-serv26193/src/zope/app/browser/form
Modified Files:
Tag: garrett-widgets-branch
editview.py vocabularywidget.py widget.py
Log Message:
CVS: ----------------------------------------------------------------------
CVS: Enter Log. Lines beginning with `CVS:' are removed automatically
CVS:
CVS: Committing in .
CVS:
CVS: Modified Files:
CVS: Tag: garrett-widgets-branch
CVS: src/zope/app/browser/cache/cacheable.py
CVS: src/zope/app/browser/component/interfacewidget.py
CVS: src/zope/app/browser/component/tests/test_interfacewidget.py
CVS: src/zope/app/browser/form/editview.py
CVS: src/zope/app/browser/form/vocabularywidget.py
CVS: src/zope/app/browser/form/widget.py
CVS: src/zope/app/browser/form/tests/test_browserwidget.py
CVS: src/zope/app/browser/form/tests/test_checkboxwidget.py
CVS: src/zope/app/browser/form/tests/test_datetimewidget.py
CVS: src/zope/app/browser/form/tests/test_editview.py
CVS: src/zope/app/browser/form/tests/test_floatwidget.py
CVS: src/zope/app/browser/form/tests/test_intwidget.py
CVS: src/zope/app/browser/form/tests/test_objectwidget.py
CVS: src/zope/app/browser/form/tests/test_sequencewidget.py
CVS: src/zope/app/browser/form/tests/test_vocabularywidget.py
CVS: src/zope/app/browser/security/permissionwidget.py
CVS: src/zope/app/browser/services/field.py
CVS: src/zope/app/browser/services/registration/__init__.py
CVS: src/zope/app/browser/services/tests/test_field_widget.py
CVS: src/zope/app/browser/skins/rotterdam/editingwidgets.py
CVS: src/zope/app/dav/configure.zcml src/zope/app/dav/widget.py
CVS: src/zope/app/form/utility.py src/zope/app/form/widget.py
CVS: src/zope/app/form/tests/test_utility.py
CVS: src/zope/app/form/tests/test_widget_geddon_deprecations.py
CVS: src/zope/app/interfaces/form.py
CVS: src/zope/schema/_bootstrapfields.py
CVS: ----------------------------------------------------------------------
Several changes related to widgets:
- Changed haveData to hasData.
- Propogated the use of Field.missing_value as an alternative to
explicit checks for None and '' (empty string).
- Changed the default implementation of hasData (was haveData) to return
True only if the one of the following was true:
- setData had been called for the widget. Per IWidget, values passed to
setData override all other data sources for a widget.
- There is a value in the request form that corresponds to the widget
field.
Prior to this change, hasData would return False if the widget's data
equaled the field's missing value. E.g., a text widget with an empty
string would return False, indicating that it has no data, even though
the empty string, a legitmate value, was submitted in the request.
This change required a handful of other changes to reflect the new
logic.
The bulk of this change effected widget.py. To see how the new logic
implementation of hasData effected widgets, see test_browserwidget.py
and test_utility.py.
- Modified the update logic for objects to skip fields that are not
present in the request form. Prior to this change, unspecified values
(i.e. values not in the request form) would cause default values to be
set for corresponding object fields.
- Exposed missing_value in initializer for Field - developers can now
specify a missing value for a schema field.
- Changed the default implementation of field validation. Prior to this
change, validation failed if a required value was missing. Now validation
is limited to validating non-missing values and the check for required
values is performed elsewhere.
- Text fields have a missing_value of '' (empty string) instead of None.
- Widget related error classes have been revamped:
- WidgetInputError, the base class for all widget related errors, now
provides two attributes: widget, the widget associated with the
error, and error_msg, a string describing the error,
- WidgetInputError implements 'args' so it can be rendered like other
errors.
- MissingInputError uses a standard error message.
- All uses of WidgetInputError and its subclasses have been updated
to use the new class.
- Deleted class zope.app.browser.form.widget.PossiblyEmptyMeansMissing.
This capability is now handled by setting a field's missing_value to ''
(empty string).
- Changed widget's _showData:
- Renamed to getUnconvertedData to clarify the method meaning and signal
its use as a public method.
- Positioned the method as a complement to getData, which returns data
in its converted form. getUnconvertedData returns data in its
unconvereted form using _unconvert.
- Renamed the 'force' argument used in various setUpWidget methods in
utility.py to 'ignore_unspecified'. This argument is set to True to
ensure that fields that are not in a form are not used to update their
corresponding widget. This argument should be true during object
updates (see editview.py) to ensure that unspecified fields are not
updated.
- Removed the 'strict' argument from applyWidgetChanges since no one was
using it and there's no clear application for it.
=== Zope3/src/zope/app/browser/form/editview.py 1.28 => 1.28.2.1 ===
--- Zope3/src/zope/app/browser/form/editview.py:1.28 Sun Jul 13 02:47:16 2003
+++ Zope3/src/zope/app/browser/form/editview.py Tue Jul 22 09:00:33 2003
@@ -62,7 +62,6 @@
def __init__(self, context, request):
super(EditView, self).__init__(context, request)
-
self._setUpWidgets()
def _setUpWidgets(self):
@@ -71,7 +70,8 @@
adapted = ContextWrapper(adapted, self.context, name='(adapted)')
self.adapted = adapted
setUpEditWidgets(self, self.schema, names=self.fieldNames,
- content=self.adapted)
+ content=self.adapted,
+ ignore_unspecified=Update in self.request)
def setPrefix(self, prefix):
for widget in self.widgets():
@@ -105,7 +105,7 @@
self.errors = errors
status = u"An error occured."
else:
- setUpEditWidgets(self, self.schema, force=1,
+ setUpEditWidgets(self, self.schema, ignore_unspecified=True,
names=self.fieldNames)
if changed:
status = "Updated %s" % datetime.utcnow()
=== Zope3/src/zope/app/browser/form/vocabularywidget.py 1.46 => 1.46.10.1 ===
--- Zope3/src/zope/app/browser/form/vocabularywidget.py:1.46 Wed Jun 25 17:18:52 2003
+++ Zope3/src/zope/app/browser/form/vocabularywidget.py Tue Jul 22 09:00:33 2003
@@ -34,6 +34,7 @@
from zope.schema.interfaces import IIterableVocabularyQuery
from zope.schema.interfaces import ValidationError
+from zope.security.proxy import trustedRemoveSecurityProxy
# These widget factories delegate to the vocabulary on the field.
@@ -85,9 +86,10 @@
# Helper functions for the factories:
def _get_vocabulary_widget(field, request, viewname):
- view = getView(field.vocabulary, "field-%s-widget" % viewname, request)
- view.setField(field)
- return view
+ view = getView(field.vocabulary, "field-%s-widget" % viewname, request)
+ view = trustedRemoveSecurityProxy(view)
+ view.setField(field)
+ return view
def _get_vocabulary_edit_widget(field, request, modifier=''):
if modifier:
@@ -185,7 +187,7 @@
def __call__(self):
if self._data is None:
- if self.haveData():
+ if self.hasData():
data = self.getData(True)
else:
data = self._getDefault()
@@ -203,36 +205,33 @@
try:
term = self.context.vocabulary.getTermByToken(token)
except LookupError:
- raise WidgetInputError(
- self.context.__name__,
- self.context.title,
+ raise WidgetInputError(self,
"token %r not found in vocabulary" % token)
else:
L.append(term.value)
return L
- _have_field_data = False
+ _has_field_data = False
def getData(self, optional=False):
data = self._compute_data()
field = self.context
if data is None:
if field.required and not optional:
- raise MissingInputError(field.__name__, field.title,
- 'the field is required')
+ raise MissingInputError(self)
return self._getDefault()
elif not optional:
try:
field.validate(data)
except ValidationError, v:
- raise WidgetInputError(self.context.__name__, self.title, v)
+ raise WidgetInputError(self, v[0])
return data
def _emptyMarker(self):
return "<input name='%s' type='hidden' value='1' />" % (
self.empty_marker_name)
- def haveData(self):
+ def hasData(self):
return (self.name in self.request.form or
self.empty_marker_name in self.request.form)
@@ -245,9 +244,10 @@
"It may be inherited from the mix-in classes SingleDataHelper\n"
"or MultiDataHelper (from zope.app.browser.form.vocabularywidget)")
- def _showData(self):
+ def getUnconvertedData(self):
raise NotImplementedError(
- "vocabulary-based widgets don't use the _showData() method")
+ "vocabulary-based widgets don't use the " \
+ "getUnconvertedData() method")
def _convert(self, value):
raise NotImplementedError(
@@ -490,7 +490,7 @@
This widget can be used when the number of selections isn't going
to be very large.
"""
- implements(implementedBy(widget.SingleItemsWidget))
+ implements(implementedBy(widget.SingleItemsWidget), )
propertyNames = VocabularyEditWidgetBase.propertyNames + ['firstItem']
firstItem = False
@@ -662,10 +662,7 @@
try:
term = self.vocabulary.getTermByToken(token)
except LookupError:
- # XXX unsure what to pass to exception constructor
- raise WidgetInputError(
- "(query view for %s)" % self.context,
- "(query view for %s)" % self.context,
+ raise WidgetInputError(self.widget,
"token %r not in vocabulary" % token)
else:
self.query_selections.append(term.value)
=== Zope3/src/zope/app/browser/form/widget.py 1.43 => 1.43.2.1 ===
--- Zope3/src/zope/app/browser/form/widget.py:1.43 Tue Jul 15 12:08:49 2003
+++ Zope3/src/zope/app/browser/form/widget.py Tue Jul 22 09:00:33 2003
@@ -54,7 +54,7 @@
'field.foo'
>>> widget.title
u'Foo'
- >>> int(widget.haveData())
+ >>> int(widget.hasData())
1
>>> widget.getData()
u'hello\\r\\nworld'
@@ -64,27 +64,21 @@
1
>>> widget.setData('Hey\\nfolks')
>>> widget.getData()
- u'hello\\r\\nworld'
+ 'Hey\\nfolks'
>>> widget.error is None
1
- >>> widget.setPrefix('test')
- >>> widget.name
- 'test.foo'
- >>> widget.error is None
- 1
- >>> int(widget.haveData())
- 0
- >>> widget.getData()
+ >>> widget.setData(field.missing_value)
+ >>> class SampleContent:
+ ... foo = 'bar'
+ >>> widget.applyChanges(SampleContent())
Traceback (most recent call last):
...
- MissingInputError: ('foo', u'Foo', u'Input is required')
- >>> widget.error is not None
- 1
+ MissingInputError: ('field.foo', u'Input is required')
>>> field.required = False
- >>> int(widget.required)
+ >>> widget.required
0
- >>> widget.getData() is None
+ >>> widget.applyChanges(SampleContent())
1
>>> widget.error is None
1
@@ -94,7 +88,7 @@
>>> setUp()
>>> print widget.label()
- <label for="test.foo">Foo</label>
+ <label for="field.foo">Foo</label>
>>> tearDown()
"""
@@ -108,43 +102,108 @@
type = 'text'
cssClass = ''
extra = ''
- _missing = None
+ _missing = ''
error = None
+
+ # marker object for field values that are unspecified - i.e. are
+ # not in the form (this is different from _missing)
+ unspecified = object()
+
+
+ def hasData(self):
+ return self._data != self._data_marker or \
+ self.name in self.request.form
+
+ def getData(self):
+ """Returns the current 'data' for the widget.
+
+ If setData was called, returns the value specified in the call.
+
+ If setData was not called, attempts to return a validated and
+ converted value using user-specified data in the form.
+
+ If the widget's field is not in the form, returns this object's
+ 'unspecified' attribute.
+
+ Raises ConversionError if the user-specified value cannot be
+ converted to a legal value for the field.
- def haveData(self):
- if self.name in self.request.form:
- return self._convert(self.request[self.name]) != self._missing
- return False
+ Raises WidgetInputError if the user-specified value violates
+ one of the field's validation rules.
+
+ If an error is raised during this method, the error is stored
+ in this object's error attribute.
+ """
- def getData(self, optional=0):
field = self.context
- value = self.request.form.get(self.name, self) # self used as marker
self.error = None
- if value is self:
- # No user input
- if field.required and not optional:
- self.error = MissingInputError(
- field.__name__, field.title, RequiredMissing
- )
- raise self.error
- return field.default
- value = self._convert(value)
- if value is not None and not optional:
+ # always return values set by setData
+ if self._data != self._data_marker:
+ return self._data
+
+ value = self.request.form.get(self.name, self.unspecified)
+ if value is self.unspecified:
+ return self.unspecified
+
+ # try to convert the value
+ try:
+ value = self._convert(value)
+ except ConversionError, e:
+ self.error = e
+ raise self.error
+
+ # validate value
+ if value != field.missing_value:
try:
field.validate(value)
- except ValidationError, v:
- self.error = WidgetInputError(self.context.__name__,
- self.title, v)
+ except ValidationError, e:
+ self.error = WidgetInputError(self, e[0])
raise self.error
+
return value
+ def getUnconvertedData(self):
+ """Returns the current data for the widget, unconverted.
+
+ Unconverted data is in a format suitable for use as the
+ widget's 'value' in an HTML form.
+
+ If setData was called, returns the value specified in the call
+ in a format suitable for HTML forms.
+
+ If setData was not called, returns the value specified by the user,
+ validated by the widget, in a form suitable for HTML forms.
+
+ If the form does not contain a value (i.e. getData returns
+ this object's unspecified attribute), returns self._getDefault().
+
+ If a value specified by the user is not valid, returns the
+ invalid value directly specified in the form. Note that self.error
+ will contain the validation error that was raised.
+
+ """
+
+ try:
+ data = self.getData()
+ except WidgetInputError, e:
+ # user specified invalid value - return original value
+ specified = self.request.form.get(self.name, self)
+ assert(specified is not self) # error shouldn't have been raised
+ return specified
+ else:
+ if data is self.unspecified:
+ return self._getDefault()
+ return self._unconvert(data)
+
def validate(self):
self.getData()
def applyChanges(self, content):
field = self.context
- value = self.getData()
+ value = self.getData() # validates and converts data
+ if value == field.missing_value and field.required:
+ raise MissingInputError(self)
change = field.query(content, self) != value
if change:
field.set(content, value)
@@ -152,25 +211,14 @@
def _convert(self, value):
if value == self._missing:
- return None
+ return self.context.missing_value
return value
def _unconvert(self, value):
- if value is None:
- return ''
+ if value == self.context.missing_value:
+ return self._missing
return value
- def _showData(self):
- if self._data is None:
- if self.haveData():
- data = self.getData(optional=1)
- else:
- data = self._getDefault()
- else:
- data = self._data
-
- return self._unconvert(data)
-
def _getDefault(self):
# Return the default value for this widget;
# may be overridden by subclasses.
@@ -181,7 +229,7 @@
type = self.getValue('type'),
name = self.name,
id = self.name,
- value = self._showData(),
+ value = self.getUnconvertedData(),
cssClass = self.getValue('cssClass'),
extra = self.getValue('extra'))
@@ -190,7 +238,7 @@
type = 'hidden',
name = self.name,
id = self.name,
- value = self._showData(),
+ value = self.getUnconvertedData(),
cssClass = self.getValue('cssClass'),
extra = self.getValue('extra'))
@@ -239,7 +287,7 @@
class DisplayWidget(BrowserWidget):
def __call__(self):
- return self._showData()
+ return self.getUnconvertedData()
class CheckBoxWidget(BrowserWidget):
"""Checkbox widget
@@ -250,7 +298,7 @@
>>> request = TestRequest(form={'field.foo.used': u'on',
... 'field.foo': u'on'})
>>> widget = CheckBoxWidget(field, request)
- >>> int(widget.haveData())
+ >>> int(widget.hasData())
1
>>> int(widget.getData())
1
@@ -310,7 +358,7 @@
extra = ''
def __call__(self):
- data = self._showData()
+ data = self.getUnconvertedData()
if data:
kw = {'checked': None}
else:
@@ -336,30 +384,13 @@
def _unconvert(self, value):
return value and "on" or ""
- return value == 'on'
- def haveData(self):
- return (
+ def hasData(self):
+ return super(CheckBoxWidget, self).hasData() or \
self.name+".used" in self.request.form
- or
- self.name in self.request.form
- )
-
- def getData(self, optional=0):
- # When it's checked, its value is 'on'.
- # When a checkbox is unchecked, it does not appear in the form data.
- value = self.request.form.get(self.name, 'off')
- return value == 'on'
-
-class PossiblyEmptyMeansMissing(BrowserWidget):
- def _convert(self, value):
- value = super(PossiblyEmptyMeansMissing, self)._convert(value)
- if not value and getattr(self.context, 'min_length', 1) > 0:
- return None
- return value
-class TextWidget(PossiblyEmptyMeansMissing, BrowserWidget):
+class TextWidget(BrowserWidget):
"""Text widget.
Single-line text (unicode) input
@@ -369,7 +400,7 @@
>>> field = TextLine(__name__='foo', title=u'on')
>>> request = TestRequest(form={'field.foo': u'Bob'})
>>> widget = TextWidget(field, request)
- >>> int(widget.haveData())
+ >>> int(widget.hasData())
1
>>> widget.getData()
u'Bob'
@@ -417,60 +448,61 @@
displayWidth = 20
displayMaxWidth = ""
extra = ''
- # XXX Alex Limi doesn't like this!
- # style = "width:100%"
style = ''
__values = None
def __init__(self, *args):
super(TextWidget, self).__init__(*args)
-
- if self.context.allowed_values is not None:
- values = list(self.context.allowed_values)
- values.sort()
+ field = self.context
+ if field.allowed_values is not None:
+ values = []
+ # If field is optional and missing_value isn't in
+ # allowed_values, add an additional option at top to
+ # represent field.missing_value.
+ if not field.required and \
+ field.missing_value not in field.allowed_values:
+ values.append(field.missing_value)
+ values += list(field.allowed_values)
self.__values = values
- if values:
- self._missing = values[-1]+'x'
- else:
- self._missing = ''
- def haveData(self):
- if super(TextWidget, self).haveData():
- if (self.request.get(self.name)
- != self._missing):
- return True
- return False
+ def _getSelectableValues(self):
+ return self.__values
def _select(self):
- selected = self._showData()
- result = ['<select id="%s" name="%s">'
- % (self.name, self.name)]
-
- values = self.__values
+ result = ['<select id="%s" name="%s">' % (self.name, self.name)]
- if not self.context.required or selected is None:
- result.append('<option value="%s"></option>' % self._missing)
+ field = self.context
+ try:
+ selected = self.getData()
+ except:
+ selected = self.getUnconvertedData()
+ values = self._getSelectableValues()
for value in values:
+ unconverted = self._unconvert(value)
if value == selected:
- result.append("<option selected>%s</option>" % value)
+ result.append('<option value="%s" selected>%s</option>' % \
+ (unconverted, unconverted))
else:
- result.append("<option>%s</option>" % value)
+ result.append('<option value="%s">%s</option>' % \
+ (unconverted, unconverted))
result.append('</select>')
return '\n\t'.join(result)
+
def __call__(self):
if self.__values is not None:
return self._select()
displayMaxWidth = self.getValue('displayMaxWidth') or 0
+
if displayMaxWidth > 0:
return renderElement(self.getValue('tag'),
type = self.getValue('type'),
name = self.name,
id = self.name,
- value = self._showData(),
+ value = self.getUnconvertedData(),
cssClass = self.getValue('cssClass'),
style = self.style,
size = self.getValue('displayWidth'),
@@ -481,12 +513,13 @@
type = self.getValue('type'),
name = self.name,
id = self.name,
- value = self._showData(),
+ value = self.getUnconvertedData(),
cssClass = self.getValue('cssClass'),
style = self.style,
size = self.getValue('displayWidth'),
extra = self.getValue('extra'))
+
class Bytes(BrowserWidget):
def _convert(self, value):
@@ -495,7 +528,7 @@
try:
value = value.encode('ascii')
except UnicodeError, v:
- raise ConversionError("Invalid textual data", v)
+ raise ConversionError(self, "Invalid textual data")
return value
@@ -509,7 +542,7 @@
>>> field = BytesLine(__name__='foo', title=u'on')
>>> request = TestRequest(form={'field.foo': u'Bob'})
>>> widget = BytesWidget(field, request)
- >>> int(widget.haveData())
+ >>> int(widget.hasData())
1
>>> widget.getData()
'Bob'
@@ -524,7 +557,9 @@
try:
return int(value)
except ValueError, v:
- raise ConversionError("Invalid integer data", v)
+ raise ConversionError(self, "Invalid integer data")
+
+ return self.context.missing_value
class FloatWidget(TextWidget):
@@ -535,7 +570,10 @@
try:
return float(value)
except ValueError, v:
- raise ConversionError("Invalid floating point data", v)
+ raise ConversionError(self, "Invalid floating point data")
+
+ return self.context.missing_value
+
class DatetimeWidget(TextWidget):
"""Datetime entry widget."""
@@ -546,9 +584,12 @@
try:
return parseDatetimetz(value)
except (DateTimeError, ValueError, IndexError), v:
- raise ConversionError("Invalid datetime data", v)
+ raise ConversionError(self, "Invalid datetime data")
-class TextAreaWidget(PossiblyEmptyMeansMissing, BrowserWidget):
+ return self.context.missing_value
+
+
+class TextAreaWidget(BrowserWidget):
"""TextArea widget.
Multi-line text (unicode) input.
@@ -558,7 +599,7 @@
>>> field = Text(__name__='foo', title=u'on')
>>> request = TestRequest(form={'field.foo': u'Hello\\r\\nworld!'})
>>> widget = TextAreaWidget(field, request)
- >>> int(widget.haveData())
+ >>> int(widget.hasData())
1
>>> widget.getData()
u'Hello\\nworld!'
@@ -626,7 +667,7 @@
rows = self.getValue('height'),
cols = self.getValue('width'),
style = self.style,
- contents = self._showData(),
+ contents = self.getUnconvertedData(),
extra = self.getValue('extra'))
class BytesAreaWidget(Bytes, TextAreaWidget):
@@ -639,7 +680,7 @@
>>> field = Bytes(__name__='foo', title=u'on')
>>> request = TestRequest(form={'field.foo': u'Hello\\r\\nworld!'})
>>> widget = BytesAreaWidget(field, request)
- >>> int(widget.haveData())
+ >>> int(widget.hasData())
1
>>> widget.getData()
'Hello\\nworld!'
@@ -702,7 +743,7 @@
size = self.getValue('displayWidth'),
extra = self.getValue('extra'))
- def haveData(self):
+ def hasData(self):
file = self.request.form.get(self.name)
if file is None:
return False
@@ -716,25 +757,21 @@
except AttributeError:
return False
- seek(0)
- if read(1):
- return True
-
- return False
+ return True
def _convert(self, value):
try:
seek = value.seek
read = value.read
except AttributeError, e:
- raise ConversionError('Value is not a file object', e)
+ raise ConversionError(self, 'Value is not a file object')
else:
seek(0)
data = read()
- if data or getattr(value, 'filename', ''):
+ if data:
return data
else:
- return None
+ return self.context.missing_value
class ItemsWidget(BrowserWidget):
@@ -800,7 +837,7 @@
size = 5
def __call__(self):
- renderedItems = self.renderItems(self._showData())
+ renderedItems = self.renderItems(self.getUnconvertedData())
return renderElement('select',
name = self.name,
id = self.name,
@@ -825,7 +862,7 @@
orientation = "vertical"
def __call__(self):
- rendered_items = self.renderItems(self._showData())
+ rendered_items = self.renderItems(self.getUnconvertedData())
orientation = self.getValue('orientation')
if orientation == 'horizontal':
return " ".join(rendered_items)
@@ -877,6 +914,9 @@
default = []
def _convert(self, value):
+ # XXX-GDS I'm not sure value will ever be None here -- maybe _missing
+ # if value == self._missing:
+ # return self.context.missing_value
if value is None:
return []
if isinstance(value, ListTypes):
@@ -926,7 +966,7 @@
size = 5
def __call__(self):
- rendered_items = self.renderItems(self._showData())
+ rendered_items = self.renderItems(self.getUnconvertedData())
return renderElement('select',
name = self.name,
id = self.name,
@@ -950,7 +990,7 @@
orientation = "vertical"
def __call__(self):
- rendered_items = self.renderItems(self._showData())
+ rendered_items = self.renderItems(self.getUnconvertedData())
orientation = self.getValue('orientation')
if orientation == 'horizontal':
return " ".join(rendered_items)
@@ -1086,6 +1126,7 @@
# XXX applyChanges isn't reporting "change" correctly (we're
# re-generating the sequence with every edit, and need to be smarter)
+ # XXX-GDS this is no different from BrowserWidget -- delete??
def applyChanges(self, content):
field = self.context
value = self.getData()
@@ -1094,7 +1135,7 @@
field.set(content, value)
return change
- def haveData(self):
+ def hasData(self):
"""Is there input data for the field
Return True if there is data and False otherwise.
@@ -1271,13 +1312,13 @@
return changes
- def haveData(self):
+ def hasData(self):
"""Is there input data for the field
Return True if there is data and False otherwise.
"""
for name, widget in self.getSubWidgets():
- if widget.haveData():
+ if widget.hasData():
return True
return False