[Checkins] SVN: z3c.sessionwidget/trunk/src/z3c/sessionwidget/ IInputWidget is now implemented by this widget, this is needed in order to update the context

Bernd Dorn bernd.dorn at fhv.at
Mon Oct 9 15:00:42 EDT 2006


Log message for revision 70590:
  IInputWidget is now implemented by this widget, this is needed in order to update the context
  implemented hasInput as required by the widget api, now it is possible to handle missing values
  fixed some imports, added tests for this
  
  

Changed:
  U   z3c.sessionwidget/trunk/src/z3c/sessionwidget/README.txt
  U   z3c.sessionwidget/trunk/src/z3c/sessionwidget/configure.zcml
  U   z3c.sessionwidget/trunk/src/z3c/sessionwidget/interfaces.py
  U   z3c.sessionwidget/trunk/src/z3c/sessionwidget/widget.py

-=-
Modified: z3c.sessionwidget/trunk/src/z3c/sessionwidget/README.txt
===================================================================
--- z3c.sessionwidget/trunk/src/z3c/sessionwidget/README.txt	2006-10-09 17:48:31 UTC (rev 70589)
+++ z3c.sessionwidget/trunk/src/z3c/sessionwidget/README.txt	2006-10-09 19:00:41 UTC (rev 70590)
@@ -37,6 +37,15 @@
   >>> import zope.interface
   >>> import zope.schema
 
+The widget class implements IInputWidget, this is needed in order to
+be handled as such in forms.
+
+  >>> from z3c.sessionwidget import widget
+  >>> from zope.app.form.interfaces import IInputWidget
+  >>> from zope.interface import verify
+  >>> verify.verifyClass(IInputWidget, widget.SessionInputWidget)
+  True
+
   >>> class IObject(zope.interface.Interface):
   ...     '''An object in the content.'''
 
@@ -69,8 +78,9 @@
 
 we can now initialize the widget:
 
-  >>> from z3c.sessionwidget import widget
   >>> objWidget = widget.SessionInputWidget(IContent['obj'], request)
+  >>> verify.verifyObject(IInputWidget, objWidget)
+  True
 
 The widget can directly access the session:
 
@@ -86,14 +96,28 @@
   >>> objWidget.hasInput()
   False
 
-Once we set the rendered value, we have soem input:
+Input widgets require that input be available in the form request. If
+input is not present, a ``MissingInputError`` is raised:
 
-  >>> objWidget.setRenderedValue(Object('1'))
+  >>> objWidget.getInputValue()
+  Traceback (most recent call last):
+  ...
+  MissingInputError: ('field.obj', u'Object', None)
+  
+This is satisfied by using a hidden field.
+
+  >>> request.form['field.obj.used'] = ''
   >>> objWidget.hasInput()
   True
+  >>> objWidget.getInputValue() is None
+  Traceback (most recent call last):
+  ...
+  WidgetInputError: ('obj', u'Object', )
 
-Of course, you can now retrieve that value:
+Ups, we have a required field, so we need an accecptable Value. We can
+achieve this by setting the rendered value.
 
+  >>> objWidget.setRenderedValue(Object('1'))
   >>> objWidget.getInputValue()
   <Object 1>
 
@@ -119,11 +143,10 @@
 When applying the changes, the method only looks at the changed flag to decide
 whether the data changed:
 
-  >>> content.obj
-
+  >>> content.obj is None
+  True
   >>> objWidget.applyChanges(content)
   True
-
   >>> content.obj
   <Object 2>
 
@@ -132,10 +155,11 @@
   >>> objWidget.session['data']
   >>> objWidget.session['changed']
 
-Note that hidden always renders empty:
+Note that hidden always renders the marker field, so that the parent
+form knows that the widget was rendered.
 
-  >>> objWidget.hidden()
-  ''
+  >>> print objWidget.hidden()
+  <input ... name="field.obj.used" type="hidden" value="" />
 
 Let's now set a new object value again, but changing the changed flag. No
 changes will be applied:

Modified: z3c.sessionwidget/trunk/src/z3c/sessionwidget/configure.zcml
===================================================================
--- z3c.sessionwidget/trunk/src/z3c/sessionwidget/configure.zcml	2006-10-09 17:48:31 UTC (rev 70589)
+++ z3c.sessionwidget/trunk/src/z3c/sessionwidget/configure.zcml	2006-10-09 19:00:41 UTC (rev 70590)
@@ -16,4 +16,14 @@
       allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher"
       />
 
+  <!-- enable to use this widget for all IObject types 
+  <view
+      type="zope.publisher.interfaces.browser.IBrowserRequest"
+      for="zope.schema.interfaces.IObject"
+      provides="zope.app.form.interfaces.IInputWidget"
+      factory=".widget.SessionInputWidget"
+      permission="zope.Public"
+      />
+  -->
+  
 </configure>

Modified: z3c.sessionwidget/trunk/src/z3c/sessionwidget/interfaces.py
===================================================================
--- z3c.sessionwidget/trunk/src/z3c/sessionwidget/interfaces.py	2006-10-09 17:48:31 UTC (rev 70589)
+++ z3c.sessionwidget/trunk/src/z3c/sessionwidget/interfaces.py	2006-10-09 19:00:41 UTC (rev 70590)
@@ -19,7 +19,7 @@
 import zope.interface
 from zope.app.form import interfaces
 
-class ISessionWidget(interfaces.IWidget):
+class ISessionWidget(interfaces.IInputWidget):
     """A widget that communicates its data via a session."""
 
     session = zope.interface.Attribute(
@@ -32,3 +32,8 @@
         ``changed`` -- a flag (boolean) describing whether the object has been
                        changed since the widget was originally initialized.
         ''')
+
+class ISessionWidgetForm(zope.interface.Interface):
+    """Marker interface for forms used in session widgets"""
+    
+    

Modified: z3c.sessionwidget/trunk/src/z3c/sessionwidget/widget.py
===================================================================
--- z3c.sessionwidget/trunk/src/z3c/sessionwidget/widget.py	2006-10-09 17:48:31 UTC (rev 70589)
+++ z3c.sessionwidget/trunk/src/z3c/sessionwidget/widget.py	2006-10-09 19:00:41 UTC (rev 70590)
@@ -23,8 +23,9 @@
 from zope.app.session.interfaces import ISession
 from zope.app.session.session import SessionPkgData
 from zope.schema.fieldproperty import FieldProperty
-
 from z3c.sessionwidget import interfaces
+from zope.app.form.interfaces import WidgetInputError, MissingInputError
+from zope.schema.interfaces import ValidationError
 
 SESSION_KEY = 'z3c.sessionwidget.SessionInputWidget'
 
@@ -46,12 +47,17 @@
     def hidden(self):
         """See zope.app.form.browser.interfaces.IBrowserWidget"""
         # Since the data is stored in a session, no data has to be passed here.
-        return ''
+        usedMarker = widget.renderElement('input',
+                                          type='hidden',
+                                          name=self.name+".used",
+                                          id=self.name+".used",
+                                          value=""
+                                          )
+        return usedMarker
 
     def hasInput(self):
-        """See zope.app.form.interfaces.IInputWidget"""
-        missing = self.context.missing_value
-        return self.session.get('data', missing) is not missing
+        """Check whether the field is represented in the form."""
+        return self.name + ".used" in self.request.form
 
     def getInputValue(self):
         """See zope.app.form.interfaces.IInputWidget"""
@@ -63,7 +69,7 @@
             raise MissingInputError(self.name, self.label, None)
 
         # Get the value from the session
-        value = self.session['data']
+        value = self.session.get('data', field.missing_value)
 
         # allow missing values only for non-required fields
         if value == field.missing_value and not field.required:
@@ -80,7 +86,10 @@
         return value
 
     def applyChanges(self, content):
-        """See zope.app.form.interfaces.IInputWidget"""
+        """See zope.app.form.interfaces.IInputWidget
+        this method is not used by formlib !!
+        XXX test this
+        """
         field = self.context
         value = self.getInputValue()
         # Look into the session to see whether the data changed
@@ -98,8 +107,8 @@
 
     def __call__(self):
         """See zope.app.form.browser.interfaces.IBrowserWidget"""
+        
         form = zope.component.getMultiAdapter(
-            (self, self.request), zope.interface.Interface,
-            'SessionInputWidget.form')
+            (self, self.request), name='SessionInputWidget.form')
         form.update()
-        return form.render()
+        return self.hidden() + form.render()



More information about the Checkins mailing list