[Checkins] SVN: zope.app.form/trunk/ Dropdown widgets display an item for the missing value even if the field is

Thomas Lotze tl at gocept.com
Thu Aug 21 05:48:44 EDT 2008


Log message for revision 90055:
  Dropdown widgets display an item for the missing value even if the field is
  required when no value is selected. The old behaviour is still available for BBB,
  but changing the default requires bumping the version to 3.6.0dev.
  

Changed:
  U   zope.app.form/trunk/CHANGES.txt
  U   zope.app.form/trunk/setup.py
  U   zope.app.form/trunk/src/zope/app/form/browser/README.txt
  U   zope.app.form/trunk/src/zope/app/form/browser/itemswidgets.py
  U   zope.app.form/trunk/src/zope/app/form/browser/source.py
  U   zope.app.form/trunk/src/zope/app/form/browser/source.txt
  U   zope.app.form/trunk/src/zope/app/form/browser/tests/test_itemswidget.py

-=-
Modified: zope.app.form/trunk/CHANGES.txt
===================================================================
--- zope.app.form/trunk/CHANGES.txt	2008-08-21 09:35:15 UTC (rev 90054)
+++ zope.app.form/trunk/CHANGES.txt	2008-08-21 09:48:43 UTC (rev 90055)
@@ -2,9 +2,13 @@
 CHANGES
 =======
 
-3.5.1 (unreleased)
+3.6.0 (unreleased)
 ==================
 
+- Dropdown widgets display an item for the missing value even if the field is
+  required when no value is selected. See zope/app/form/browser/README.txt on
+  how to switch this off for BBB.
+
 3.5.0 (2008-06-05)
 ==================
 

Modified: zope.app.form/trunk/setup.py
===================================================================
--- zope.app.form/trunk/setup.py	2008-08-21 09:35:15 UTC (rev 90054)
+++ zope.app.form/trunk/setup.py	2008-08-21 09:48:43 UTC (rev 90055)
@@ -22,7 +22,7 @@
     return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
 
 setup(name='zope.app.form',
-      version = '3.5.1dev',
+      version = '3.6.0dev',
       author='Zope Corporation and Contributors',
       author_email='zope3-dev at zope.org',
       description='The Original Zope 3 Form Framework',

Modified: zope.app.form/trunk/src/zope/app/form/browser/README.txt
===================================================================
--- zope.app.form/trunk/src/zope/app/form/browser/README.txt	2008-08-21 09:35:15 UTC (rev 90054)
+++ zope.app.form/trunk/src/zope/app/form/browser/README.txt	2008-08-21 09:48:43 UTC (rev 90055)
@@ -152,3 +152,27 @@
       factory=".BagWidget"
       permission="zope.Public"
       />
+
+
+Choice widgets and the missing value
+====================================
+
+Choice widgets for a non-required field include a "no value" item to allow for
+not selecting any value at all. This value used to be omitted for required
+fields on the assumption that the widget should avoid invalid input from the
+start.
+
+However, if the context object doesn't yet have a field value set and there's
+no default value, a dropdown widget would have to select an arbitrary value
+due to the way it is displayed in the browser. This way, the field would
+always validate, but possibly with a value the user never chose consciously.
+
+Starting with version 3.6.0, dropdown widgets for required fields display a
+"no value" item even for required fields if an arbitrary value would have to
+be selected by the widget otherwise.
+
+To switch the old behaviour back on for backwards compatibility, do
+
+  zope.app.form.browser.itemswidgets.EXPLICIT_EMPTY_SELECTION = False
+
+during application start-up.

Modified: zope.app.form/trunk/src/zope/app/form/browser/itemswidgets.py
===================================================================
--- zope.app.form/trunk/src/zope/app/form/browser/itemswidgets.py	2008-08-21 09:35:15 UTC (rev 90054)
+++ zope.app.form/trunk/src/zope/app/form/browser/itemswidgets.py	2008-08-21 09:48:43 UTC (rev 90055)
@@ -297,6 +297,11 @@
 
 ## Edit-Widgets for Items-related fields.
 
+# BBB Set to False to never display an item for the missing value if the field
+# is required, which was the behaviour of versions up to and including 3.5.0.
+EXPLICIT_EMPTY_SELECTION = True
+
+
 class ItemsEditWidgetBase(SingleDataHelper, ItemsWidgetBase):
     """Widget Base for rendering item-related fields.
 
@@ -310,6 +315,10 @@
 
     _displayItemForMissingValue = True
 
+    # Whether an empty selection should always be made explicit, i.e. even
+    # if the field is required.
+    explicit_empty_selection = False
+
     def __init__(self, field, vocabulary, request):
         """Initialize the widget."""
         super(ItemsEditWidgetBase, self).__init__(field, vocabulary, request)
@@ -359,7 +368,13 @@
         # Handle case of missing value
         missing = self._toFormValue(self.context.missing_value)
 
-        if self._displayItemForMissingValue and not self.context.required:
+        if self._displayItemForMissingValue and (
+            not self.context.required or
+            EXPLICIT_EMPTY_SELECTION and
+            self.explicit_empty_selection and
+            missing in values and
+            self.context.default is None):
+
             if missing in values:
                 render = self.renderSelectedItem
             else:
@@ -432,6 +447,7 @@
 class DropdownWidget(SelectWidget):
     """Variation of the SelectWidget that uses a drop-down list."""
     size = 1
+    explicit_empty_selection = True
 
 
 class RadioWidget(SelectWidget):

Modified: zope.app.form/trunk/src/zope/app/form/browser/source.py
===================================================================
--- zope.app.form/trunk/src/zope/app/form/browser/source.py	2008-08-21 09:35:15 UTC (rev 90054)
+++ zope.app.form/trunk/src/zope/app/form/browser/source.py	2008-08-21 09:48:43 UTC (rev 90055)
@@ -560,6 +560,7 @@
     """Variation of the SourceSelectWidget that uses a drop-down list."""
 
     size = 1
+    explicit_empty_selection = True
 
 class SourceRadioWidget(RadioWidget):
     """Radio widget for single item choices."""

Modified: zope.app.form/trunk/src/zope/app/form/browser/source.txt
===================================================================
--- zope.app.form/trunk/src/zope/app/form/browser/source.txt	2008-08-21 09:35:15 UTC (rev 90054)
+++ zope.app.form/trunk/src/zope/app/form/browser/source.txt	2008-08-21 09:48:43 UTC (rev 90055)
@@ -162,8 +162,9 @@
   >>> print widget() # doctest: +ELLIPSIS
   <div>
   <div class="value">
-  <select id="field.dog" name="field.dog" size="1" >...
-  
+  <select id="field.dog" name="field.dog" size="1" >
+  <option selected="selected" value="">(no value)</option>...
+
 An alternative to SourceSelectWidget for small numbers of items is
 SourceRadioWidget that provides a radio button group for the items::
 

Modified: zope.app.form/trunk/src/zope/app/form/browser/tests/test_itemswidget.py
===================================================================
--- zope.app.form/trunk/src/zope/app/form/browser/tests/test_itemswidget.py	2008-08-21 09:35:15 UTC (rev 90054)
+++ zope.app.form/trunk/src/zope/app/form/browser/tests/test_itemswidget.py	2008-08-21 09:48:43 UTC (rev 90055)
@@ -24,6 +24,7 @@
 from zope.publisher.browser import TestRequest
 
 from zope.app.form.interfaces import ConversionError
+import zope.app.form.browser.itemswidgets
 from zope.app.form.browser.itemswidgets import ItemsWidgetBase
 from zope.app.form.browser.itemswidgets import ItemDisplayWidget
 from zope.app.form.browser.itemswidgets import ItemsMultiDisplayWidget
@@ -320,7 +321,28 @@
     _widget = DropdownWidget
     _size = 1
 
+    def test_renderItems_firstItem(self):
+        widget = self._makeWidget()
+        widget.setPrefix('field.')
+        widget.firstItem = True
+        self.assertEqual(
+            widget.renderItems(widget._toFormValue(widget.context.missing_value)),
+            [u'<option selected="selected" value="">(no value)</option>',
+             u'<option value="token1">One</option>',
+             u'<option value="token2">Two</option>',
+             u'<option value="token3">Three</option>'])
+        try:
+            # test BBB starting with 3.6.0
+            zope.app.form.browser.itemswidgets.EXPLICIT_EMPTY_SELECTION = False
+            self.assertEqual(
+                widget.renderItems(widget._toFormValue(widget.context.missing_value)),
+                [u'<option value="token1">One</option>',
+                 u'<option value="token2">Two</option>',
+                 u'<option value="token3">Three</option>'])
+        finally:
+            zope.app.form.browser.itemswidgets.EXPLICIT_EMPTY_SELECTION = True
 
+
 class RadioWidgetTest(ItemsEditWidgetBaseTest):
 
     _widget = RadioWidget



More information about the Checkins mailing list