[Zope3-checkins] SVN: Zope3/branches/3.3/ - Fixed issue 592: RadioWidget never renders '(no value)' as selected

Christian Theune cvs-admin at zope.org
Sun Jun 18 01:36:03 EDT 2006


Log message for revision 68730:
   - Fixed issue 592:  RadioWidget never renders '(no value)' as selected
  - Dies und die folgenden Zeilen werden ignoriert --
  
  M    src/zope/app/form/tests/test_widget.py
  M    src/zope/app/form/browser/tests/test_radiowidget.py
  M    src/zope/app/form/browser/tests/test_itemswidget.py
  M    src/zope/app/form/browser/itemswidgets.py
  AM   src/zope/app/form/browser/ftests/test_selectwidget.py
  M    src/zope/app/form/browser/ftests/test_textwidget.py
  M    doc/CHANGES.txt
  

Changed:
  U   Zope3/branches/3.3/doc/CHANGES.txt
  A   Zope3/branches/3.3/src/zope/app/form/browser/ftests/test_selectwidget.py
  U   Zope3/branches/3.3/src/zope/app/form/browser/ftests/test_textwidget.py
  U   Zope3/branches/3.3/src/zope/app/form/browser/itemswidgets.py
  U   Zope3/branches/3.3/src/zope/app/form/browser/tests/test_itemswidget.py
  U   Zope3/branches/3.3/src/zope/app/form/browser/tests/test_radiowidget.py
  U   Zope3/branches/3.3/src/zope/app/form/tests/test_widget.py

-=-
Modified: Zope3/branches/3.3/doc/CHANGES.txt
===================================================================
--- Zope3/branches/3.3/doc/CHANGES.txt	2006-06-18 05:26:25 UTC (rev 68729)
+++ Zope3/branches/3.3/doc/CHANGES.txt	2006-06-18 05:35:59 UTC (rev 68730)
@@ -10,6 +10,9 @@
 
     Bugfixes
 
+      - Fixed issue 592: Made handling of '(no value)' entries for selection
+        widgets cleaner and consistent
+
       - Fixed issue 634: Changed lookup for pre-marshallers to use component
         architecture.
     

Added: Zope3/branches/3.3/src/zope/app/form/browser/ftests/test_selectwidget.py
===================================================================
--- Zope3/branches/3.3/src/zope/app/form/browser/ftests/test_selectwidget.py	2006-06-18 05:26:25 UTC (rev 68729)
+++ Zope3/branches/3.3/src/zope/app/form/browser/ftests/test_selectwidget.py	2006-06-18 05:35:59 UTC (rev 68730)
@@ -0,0 +1,145 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""RadioWidget Tests
+
+$Id$
+"""
+import unittest
+import transaction
+from persistent import Persistent
+
+import zope.security.checker
+from zope.interface import Interface, implements
+from zope.schema import TextLine, Choice
+from zope.traversing.api import traverse
+
+from zope.app.form.browser.ftests.support import *
+from zope.app.testing.functional import BrowserTestCase
+
+class IRadioTest(Interface):
+
+    s3 = Choice(
+        required=False,
+        values=(u'Bob', u'is', u'Your', u'Uncle'))
+
+    s4 = Choice(
+        required=True,
+        values=(u'1', u'2', u'3'))
+
+class RadioTest(Persistent):
+
+    implements(IRadioTest)
+
+    def __init__(self):
+        self.s3 = None
+        self.s4 = u'1'
+
+class Test(BrowserTestCase):
+
+    def setUp(self):
+        BrowserTestCase.setUp(self)
+        registerEditForm(IRadioTest)
+        defineSecurity(RadioTest, IRadioTest)
+
+    def test_display_editform(self):
+        self.getRootFolder()['test'] = RadioTest()
+        transaction.commit()
+
+        test = self.getRootFolder()['test']
+        test.s3 = u"Bob"
+
+        # display edit view
+        response = self.publish('/test/edit.html')
+        self.assertEqual(response.getStatus(), 200)
+
+        # S3
+        self.assert_(patternExists(
+            '<select .* name="field.s3".*>',
+            response.getBody()))
+        self.assert_(patternExists(
+            '<option selected="selected" value="">',
+            response.getBody()))
+        self.assert_(patternExists(
+            '<option value="Bob">',
+            response.getBody()))
+        self.assert_(patternExists(
+            '<option value="is">',
+            response.getBody()))
+        self.assert_(patternExists(
+            '<option value="Your">',
+            response.getBody()))
+        self.assert_(patternExists(
+            '<option value="Uncle">',
+            response.getBody()))
+
+        # S4
+        joined_body = "".join(response.getBody().split("\n"))
+        self.failIf(patternExists(
+            '<select.*name="field.s4".*>.*<option.*value="".*>',
+            joined_body))
+        self.assert_(patternExists(
+            '<select .* name="field.s4".*>',
+            response.getBody()))
+        self.assert_(patternExists(
+            '<option selected="selected" value="1">',
+            response.getBody()))
+        self.assert_(patternExists(
+            '<option value="2">',
+            response.getBody()))
+        self.assert_(patternExists(
+            '<option value="3">',
+            response.getBody()))
+
+        response = self.publish('/test/edit.html', form={
+            'UPDATE_SUBMIT': '',
+            'field.s3': u'Bob',
+            'field.s4': u'2'})
+        self.assert_(patternExists(
+            '<option selected="selected" value="Bob">',
+            response.getBody()))
+        self.assert_(patternExists(
+            '<option selected="selected" value="2">',
+            response.getBody()))
+
+        response = self.publish('/test/edit.html')
+        self.assert_(patternExists(
+            '<option selected="selected" value="Bob">',
+            response.getBody()))
+        self.assert_(patternExists(
+            '<option selected="selected" value="2">',
+            response.getBody()))
+
+        response = self.publish('/test/edit.html', form={
+            'UPDATE_SUBMIT': '',
+            'field.s3': u''})
+        self.assert_(patternExists(
+            '<option selected="selected" value="">',
+            response.getBody()))
+        self.assert_(patternExists(
+            '<option selected="selected" value="2">',
+            response.getBody()))
+
+        response = self.publish('/test/edit.html')
+        self.assert_(patternExists(
+            '<option selected="selected" value="">',
+            response.getBody()))
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(Test))
+    return suite
+
+if __name__=='__main__':
+    unittest.main(defaultTest='test_suite')
+


Property changes on: Zope3/branches/3.3/src/zope/app/form/browser/ftests/test_selectwidget.py
___________________________________________________________________
Name: svn:keywords
   + Id Rev Date
Name: svn:eol-style
   + native

Modified: Zope3/branches/3.3/src/zope/app/form/browser/ftests/test_textwidget.py
===================================================================
--- Zope3/branches/3.3/src/zope/app/form/browser/ftests/test_textwidget.py	2006-06-18 05:26:25 UTC (rev 68729)
+++ Zope3/branches/3.3/src/zope/app/form/browser/ftests/test_textwidget.py	2006-06-18 05:35:59 UTC (rev 68730)
@@ -79,7 +79,7 @@
         self.assert_(patternExists(
             '<select .*name="field.s3".*>', response.getBody()))
         self.assert_(patternExists(
-            '<option value="">.*</option>', response.getBody()))
+            '<option selected="selected" value="">.*</option>', response.getBody()))
 
 
     def test_submit_editform(self):

Modified: Zope3/branches/3.3/src/zope/app/form/browser/itemswidgets.py
===================================================================
--- Zope3/branches/3.3/src/zope/app/form/browser/itemswidgets.py	2006-06-18 05:26:25 UTC (rev 68729)
+++ Zope3/branches/3.3/src/zope/app/form/browser/itemswidgets.py	2006-06-18 05:35:59 UTC (rev 68730)
@@ -309,8 +309,9 @@
 
     size = 5
     tag = 'select'
-    firstItem = False
 
+    _displayItemForMissingValue = True
+
     def __init__(self, field, vocabulary, request):
         """Initialize the widget."""
         super(ItemsEditWidgetBase, self).__init__(field, vocabulary, request)
@@ -356,22 +357,39 @@
         # vocabulary, so that need not be considered here
         rendered_items = []
         count = 0
+
+        # Handle case of missing value
+        missing = self._toFormValue(self.context.missing_value)
+
+        if self._displayItemForMissingValue and not self.context.required:
+            if missing in values:
+                render = self.renderSelectedItem
+            else:
+                render = self.renderItem
+
+            missing_item = render(count,
+                self.translate(self._messageNoValue),
+                missing,
+                self.name,
+                cssClass)
+            rendered_items.append(missing_item)
+            count += 1
+
+        # Render normal values
         for term in self.vocabulary:
             item_text = self.textForValue(term)
 
             if term.value in values:
-                rendered_item = self.renderSelectedItem(count,
-                                                        item_text,
-                                                        term.token,
-                                                        self.name,
-                                                        cssClass)
+                render = self.renderSelectedItem
             else:
-                rendered_item = self.renderItem(count,
-                                                item_text,
-                                                term.token,
-                                                self.name,
-                                                cssClass)
+                render = self.renderItem
 
+            rendered_item = render(count,
+                item_text,
+                term.token,
+                self.name,
+                cssClass)
+
             rendered_items.append(rendered_item)
             count += 1
 
@@ -410,22 +428,7 @@
                              extra=self.extra)
 
     def renderItems(self, value):
-        # check if we want to select first item
-        if (value == self.context.missing_value
-            and getattr(self, 'firstItem', False)
-            and len(self.vocabulary) > 0):
-            # Grab the first item from the iterator:
-            values = [iter(self.vocabulary).next().value]
-        elif value != self.context.missing_value:
-            values = [value]
-        else:
-            values = []
-        items = self.renderItemsWithValues(values)
-        if not self.context.required:
-            option = ('<option value="">%s</option>'
-                      %(self.translate(self._messageNoValue)))
-            items.insert(0, option)
-        return items
+        return self.renderItemsWithValues([value])
 
 
 class DropdownWidget(SelectWidget):
@@ -433,7 +436,7 @@
     size = 1
 
 
-class RadioWidget(ItemsEditWidgetBase):
+class RadioWidget(SelectWidget):
     """Radio widget for single item choices.
 
     This widget can be used when the number of selections is going
@@ -469,40 +472,6 @@
                              type='radio')
         return self._joinButtonToMessageTemplate %(elem, text)
 
-    def renderItems(self, value):
-        # check if we want to select first item, the previously selected item
-        # or the "no value" item.
-        no_value = None
-        if (value == self.context.missing_value
-            and getattr(self, 'firstItem', False)
-            and len(self.vocabulary) > 0):
-            if self.context.required:
-                # Grab the first item from the iterator:
-                values = [iter(self.vocabulary).next().value]
-            else:
-                # the "no value" option will be checked
-                no_value = 'checked'
-        elif value != self.context.missing_value:
-            values = [value]
-        else:
-            values = []
-
-        items = self.renderItemsWithValues(values)
-        if not self.context.required:
-            kwargs = {
-                'value': '',
-                'name': self.name,
-                'cssClass': self.cssClass,
-                'type': 'radio'}
-            if no_value:
-                kwargs['checked']=no_value
-            option = renderElement('input', **kwargs)
-            option = self._joinButtonToMessageTemplate %(
-                option, self.translate(self._messageNoValue))
-            items.insert(0, option)
-
-        return items
-
     def renderValue(self, value):
         rendered_items = self.renderItems(value)
         if self.orientation == 'horizontal':
@@ -516,6 +485,7 @@
 
     _messageNoValue = _("vocabulary-missing-multiple-value-for-edit",
                         "(no values)")
+    _displayItemForMissingValue = False
 
     def renderItems(self, value):
         if value == self.context.missing_value:

Modified: Zope3/branches/3.3/src/zope/app/form/browser/tests/test_itemswidget.py
===================================================================
--- Zope3/branches/3.3/src/zope/app/form/browser/tests/test_itemswidget.py	2006-06-18 05:26:25 UTC (rev 68729)
+++ Zope3/branches/3.3/src/zope/app/form/browser/tests/test_itemswidget.py	2006-06-18 05:35:59 UTC (rev 68730)
@@ -301,8 +301,8 @@
         widget.setPrefix('field.')
         widget.firstItem = True
         self.assertEqual(
-            widget.renderItems(None),
-            [u'<option selected="selected" value="token1">One</option>',
+            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>'])
 
@@ -381,8 +381,8 @@
 
     def test_renderItems_firstItem(self):
         widget = self._makeWidget()
-        widget.firstItem = True
-        items = widget.renderItems(None)
+        items = widget.renderItems(
+                widget._toFormValue(widget.context.missing_value))
         values = [('token1','One'), ('token2','Two'), ('token3','Three')]
         for index, item in enumerate(items):
             self.verifyResult(
@@ -390,7 +390,6 @@
                 ['<label', '<input', 'class="radioType"', 'name="field.choice"',
                  'id="field.choice.%i"' %index, 'type="radio"',
                  'value="%s"' %values[index][0], '&nbsp;%s' %values[index][1]])
-        self.verifyResult(items[0], ['checked="checked"'])
 
     def test_renderValue(self):
         widget = self._makeWidget()
@@ -415,6 +414,19 @@
              '>One</option>\n', 'value="token2"', '>Two</option>\n',
              'value="token3"', '>Three</option>', '</select>'])
 
+    def test_renderItemsWithValues(self):
+        widget = self._makeWidget()
+        self.assertEqual(
+            widget.renderItemsWithValues(['one', 'two']),
+            [u'<option selected="selected" value="token1">One</option>',
+             u'<option selected="selected" value="token2">Two</option>',
+             u'<option value="token3">Three</option>'])
+        self.assertEqual(
+            widget.renderItemsWithValues([]),
+            [u'<option value="token1">One</option>',
+             u'<option value="token2">Two</option>',
+             u'<option value="token3">Three</option>'])
+
 # This test is disabled because it tests for the presense of a missfeature,
 # which has been removed.  Did someone actually *want* this?
 ##     def test_error(self):

Modified: Zope3/branches/3.3/src/zope/app/form/browser/tests/test_radiowidget.py
===================================================================
--- Zope3/branches/3.3/src/zope/app/form/browser/tests/test_radiowidget.py	2006-06-18 05:26:25 UTC (rev 68729)
+++ Zope3/branches/3.3/src/zope/app/form/browser/tests/test_radiowidget.py	2006-06-18 05:35:59 UTC (rev 68730)
@@ -55,7 +55,6 @@
     def testProperties(self):
         self.assertEqual(self._widget.cssClass, "")
         self.assertEqual(self._widget.extra, '')
-        self.assertEqual(self._widget.firstItem, 0)
         self.assertEqual(self._widget.orientation, 'vertical')
 
 

Modified: Zope3/branches/3.3/src/zope/app/form/tests/test_widget.py
===================================================================
--- Zope3/branches/3.3/src/zope/app/form/tests/test_widget.py	2006-06-18 05:26:25 UTC (rev 68729)
+++ Zope3/branches/3.3/src/zope/app/form/tests/test_widget.py	2006-06-18 05:35:59 UTC (rev 68730)
@@ -201,6 +201,7 @@
 
     """
 
+
 # BBB: Gone in 3.3 (does not satify IViewFactory)
 class TestCustomSequenceWidgetFactory(object):
     """Tests the custom sequence widget factory.



More information about the Zope3-Checkins mailing list