[Checkins] SVN: z3c.form/branches/adamg-objectwidget/src/z3c/form/ works, code cleanup done

Adam Groszer agroszer at gmail.com
Wed Oct 8 05:30:09 EDT 2008


Log message for revision 91902:
  works, code cleanup done
  

Changed:
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.py
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.txt
  D   z3c.form/branches/adamg-objectwidget/src/z3c/form/dummy.py
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/interfaces.py
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/object.py
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/testing.py

-=-
Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.py	2008-10-08 08:18:09 UTC (rev 91901)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.py	2008-10-08 09:30:09 UTC (rev 91902)
@@ -6,6 +6,7 @@
 from z3c.form import form, interfaces
 from z3c.form.widget import Widget, FieldWidget
 from z3c.form.browser import widget
+from z3c.form.error import MultipleErrors
 
 from z3c.form.object import ObjectSubForm
 
@@ -16,51 +17,46 @@
     subform = None
     _value = interfaces.NOVALUE
 
-    #def updateWidgets(self):
-    #    #if self.subform is None:
-    #    if self._value is not interfaces.NOVALUE:
-    #        subobj = self._value
-    #    else:
-    #        try:
-    #            subobj = getattr(self.context, self.field.__name__)
-    #        except AttributeError:
-    #            #lame, mostly for adding
-    #            subobj = self.context
-    #    self.subform = ObjectSubForm(subobj, self)
-    #    #self.subform = ObjectSubForm(self.value, self)
-    #    self.subform.update()
     def updateWidgets(self):
-        #if self.subform is None:
-        try:
-            subobj = getattr(self.context, self.field.__name__)
-        except AttributeError:
-            if self.value:
-                subobj = self.value
-            else:
-                #lame, mostly for adding
-                subobj = self.context
-        self.subform = ObjectSubForm(subobj, self)
-        #self.subform = ObjectSubForm(self.value, self)
+        if self._value is not interfaces.NOVALUE:
+            self.subform = ObjectSubForm(self._value, self)
+        else:
+            self.subform = ObjectSubForm(None, self)
+            self.subform.ignoreContext=True
+
         self.subform.update()
 
     def update(self):
+        try:
+            self._value = getattr(self.context, self.field.__name__)
+        except AttributeError:
+            #lame, mostly for adding
+            if self.context is not None:
+                self._value = self.context
+
         super(ObjectWidget, self).update()
         self.updateWidgets()
 
-    #@apply
-    #def value():
-    #    """This invokes updateWidgets on any value change e.g. update/extract."""
-    #    def get(self):
-    #        return self.extract()
-    #    def set(self, value):
-    #        if isinstance(value, tuple):
-    #            from pub.dbgpclient import brk; brk('192.168.32.1')
-    #
-    #        self._value = value
-    #        # ensure that we apply our new values to the widgets
-    #        self.updateWidgets()
-    #    return property(get, set)
+    @apply
+    def value():
+        """This invokes updateWidgets on any value change e.g. update/extract."""
+        def get(self):
+            return self.extract()
+        def set(self, value):
+            if isinstance(value, tuple):
+                try:
+                    value = interfaces.IDataConverter(self).toFieldValue(value)
+                    self._value = value
+                except (zope.schema.ValidationError,
+                    ValueError, MultipleErrors), error:
+                    pass
+            else:
+                self._value = value
 
+            # ensure that we apply our new values to the widgets
+            self.updateWidgets()
+        return property(get, set)
+
     def extract(self, default=interfaces.NOVALUE):
         if self.name+'-empty-marker' in self.request:
             self.updateWidgets()

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.txt
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.txt	2008-10-08 08:18:09 UTC (rev 91901)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.txt	2008-10-08 09:30:09 UTC (rev 91902)
@@ -18,13 +18,16 @@
 
 
 
-  >>> from z3c.form.dummy import MySubObjectFactory
-  >>> from z3c.form.dummy import MySecondFactory
+  >>> from z3c.form.testing import IMySubObject
+  >>> from z3c.form.testing import IMySecond
+  >>> from z3c.form.testing import MySubObject
+  >>> from z3c.form.testing import MySecond
 
   >>> import zope.component
 
-  >>> zope.component.provideAdapter(MySubObjectFactory, name='IMySubObject')
-  >>> zope.component.provideAdapter(MySecondFactory, name='IMySecond')
+  >>> from z3c.form.object import registerFactoryAdapter
+  >>> registerFactoryAdapter(IMySubObject, MySubObject)
+  >>> registerFactoryAdapter(IMySecond, MySecond)
 
   >>> from z3c.form.error import MultipleErrorViewSnippet
   >>> zope.component.provideAdapter(MultipleErrorViewSnippet)
@@ -65,7 +68,7 @@
 This schema is specified by the field:
 
   >>> from z3c.form.widget import FieldWidget
-  >>> from z3c.form.dummy import IMySubObject
+  >>> from z3c.form.testing import IMySubObject
   >>> import zope.schema
   >>> field = zope.schema.Object(
   ...     __name__='subobject',
@@ -107,7 +110,9 @@
           </label>
         </div>
         <div class="widget">
-          <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="1,111">
+          <input class="text-widget required int-field"
+          id="subobject-widgets-foofield" name="subobject.widgets.foofield"
+          type="text" value="1,111">
         </div>
         <div class="label">
           <label for="subobject-widgets-barfield">
@@ -115,7 +120,8 @@
           </label>
         </div>
         <div class="widget">
-          <input class="text-widget int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="2,222">
+          <input class="text-widget int-field" id="subobject-widgets-barfield"
+          name="subobject.widgets.barfield" type="text" value="2,222">
         </div>
         <input name="subobject-empty-marker" type="hidden" value="1">
       </div>
@@ -127,17 +133,17 @@
 
 Let's provide a more meaningful value:
 
-  >>> from z3c.form.dummy import MySubObject
+  >>> from z3c.form.testing import MySubObject
   >>> v = MySubObject()
   >>> v.foofield = 42
   >>> v.barfield = 666
 
+
+  >>> widget.ignoreContext = False
   >>> widget.value = v
-  >>> widget.ignoreContext = False
 
-#>>> from pub.dbgpclient import brk; brk('192.168.32.1')
+  >>> widget.update()
 
-  >>> widget.update()
   >>> print widget.render()
   <html>
     <body>
@@ -149,7 +155,9 @@
           </label>
         </div>
         <div class="widget">
-          <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="42">
+          <input class="text-widget required int-field"
+          id="subobject-widgets-foofield" name="subobject.widgets.foofield"
+          type="text" value="42">
         </div>
         <div class="label">
           <label for="subobject-widgets-barfield">
@@ -157,7 +165,8 @@
           </label>
         </div>
         <div class="widget">
-          <input class="text-widget int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="666">
+          <input class="text-widget int-field" id="subobject-widgets-barfield"
+          name="subobject.widgets.barfield" type="text" value="666">
         </div>
         <input name="subobject-empty-marker" type="hidden" value="1">
       </div>
@@ -180,7 +189,9 @@
           </label>
         </div>
         <div class="widget">
-          <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="2">
+          <input class="text-widget required int-field"
+          id="subobject-widgets-foofield" name="subobject.widgets.foofield"
+          type="text" value="2">
         </div>
         <div class="label">
           <label for="subobject-widgets-barfield">
@@ -188,7 +199,8 @@
           </label>
         </div>
         <div class="widget">
-          <input class="text-widget int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="999">
+          <input class="text-widget int-field" id="subobject-widgets-barfield"
+          name="subobject.widgets.barfield" type="text" value="999">
         </div>
         <input name="subobject-empty-marker" type="hidden" value="1">
       </div>
@@ -203,8 +215,6 @@
   ...                                    'subobject.widgets.barfield':u'bad'})
 
 
-#  >>> from pub.dbgpclient import brk; brk('192.168.32.1')
-
   >>> widget.update()
   >>> print widget.render()
   <html>
@@ -217,7 +227,9 @@
           </label>
         </div>
         <div class="widget">
-          <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="2">
+          <input class="text-widget required int-field"
+          id="subobject-widgets-foofield" name="subobject.widgets.foofield"
+          type="text" value="2">
         </div>
         <div class="label">
           <label for="subobject-widgets-barfield">
@@ -228,7 +240,8 @@
           <div class="error">The entered value is not a valid integer literal.</div>
         </div>
         <div class="widget">
-          <input class="text-widget int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="bad">
+          <input class="text-widget int-field" id="subobject-widgets-barfield"
+          name="subobject.widgets.barfield" type="text" value="bad">
         </div>
         <input name="subobject-empty-marker" type="hidden" value="1">
       </div>
@@ -255,7 +268,7 @@
 We define an interface containing a subobject, and an addform for it:
 
   >>> from z3c.form import form, field
-  >>> from z3c.form.dummy import MyObject, IMyObject
+  >>> from z3c.form.testing import MyObject, IMyObject
 
 Note, that creating an object will print some information about it:
 
@@ -274,8 +287,6 @@
   >>> request = TestRequest()
   >>> myaddform =  MyAddForm(root, request)
 
-#>>> from pub.dbgpclient import brk; brk('192.168.32.1')
-
   >>> myaddform.update()
 
 As usual, the form contains a widget manager with the expected widget
@@ -322,7 +333,9 @@
               </label>
             </div>
             <div class="widget">
-              <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="1,111">
+              <input class="text-widget required int-field"
+              id="subobject-widgets-foofield" name="subobject.widgets.foofield"
+              type="text" value="1,111">
             </div>
             <div class="label">
               <label for="subobject-widgets-barfield">
@@ -330,9 +343,11 @@
               </label>
             </div>
             <div class="widget">
-              <input class="text-widget int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="2,222">
+              <input class="text-widget int-field" id="subobject-widgets-barfield"
+              name="subobject.widgets.barfield" type="text" value="2,222">
             </div>
-            <input name="form.widgets.subobject-empty-marker" type="hidden" value="1">
+            <input name="form.widgets.subobject-empty-marker" type="hidden"
+            value="1">
           </div>
         </div>
         <div class="row">
@@ -340,12 +355,21 @@
           <input class="text-widget required textline-field" id="form-widgets-name" name="form.widgets.name" type="text" value="">
         </div>
         <div class="action">
-          <input class="submit-widget button-field" id="form-buttons-add" name="form.buttons.add" type="submit" value="Add">
+          <input class="submit-widget button-field" id="form-buttons-add"
+          name="form.buttons.add" type="submit" value="Add">
         </div>
       </form>
     </body>
   </html>
 
+
+We don't have the object (yet) in the root:
+
+  >>> root['first']
+  Traceback (most recent call last):
+  ...
+  KeyError: 'first'
+
 Let's try to add an object:
 
   >>> request = TestRequest(form={'subobject.widgets.foofield':u'66',
@@ -355,25 +379,26 @@
   ...                             'form.buttons.add':'Add'})
   >>> myaddform.request = request
   >>> myaddform.update()
-  MyAddForm.create {'subobject': <z3c.form.dummy.MySubObject object at ...>,
+  MyAddForm.create {'subobject': <z3c.form.testing.MySubObject object at ...>,
   'name': u'first'}
 
 Wow, it got added:
 
   >>> root['first']
-  <z3c.form.dummy.MyObject object at ...>
+  <z3c.form.testing.MyObject object at ...>
 
   >>> root['first'].subobject
-  <z3c.form.dummy.MySubObject object at ...>
+  <z3c.form.testing.MySubObject object at ...>
 
+Field values need to be right:
+
   >>> root['first'].subobject.foofield
   66
-
   >>> root['first'].subobject.barfield
   99
 
+Let's try to edit that newly added object:
 
-
   >>> class MyEditForm(form.EditForm):
   ...     fields = field.Fields(IMyObject)
 
@@ -381,6 +406,8 @@
   >>> addTemplate(editform)
   >>> editform.update()
 
+Watch for the widget values in the HTML:
+
   >>> print editform.render()
   <html xmlns="http://www.w3.org/1999/xhtml">
     <body>
@@ -395,7 +422,9 @@
               </label>
             </div>
             <div class="widget">
-              <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="66">
+              <input class="text-widget required int-field"
+              id="subobject-widgets-foofield" name="subobject.widgets.foofield"
+              type="text" value="66">
             </div>
             <div class="label">
               <label for="subobject-widgets-barfield">
@@ -403,22 +432,27 @@
               </label>
             </div>
             <div class="widget">
-              <input class="text-widget int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="99">
+              <input class="text-widget int-field" id="subobject-widgets-barfield"
+              name="subobject.widgets.barfield" type="text" value="99">
             </div>
-            <input name="form.widgets.subobject-empty-marker" type="hidden" value="1">
+            <input name="form.widgets.subobject-empty-marker" type="hidden"
+            value="1">
           </div>
         </div>
         <div class="row">
           <label for="form-widgets-name">name</label>
-          <input class="text-widget required textline-field" id="form-widgets-name" name="form.widgets.name" type="text" value="first">
+          <input class="text-widget required textline-field" id="form-widgets-name"
+          name="form.widgets.name" type="text" value="first">
         </div>
         <div class="action">
-          <input class="submit-widget button-field" id="form-buttons-apply" name="form.buttons.apply" type="submit" value="Apply">
+          <input class="submit-widget button-field" id="form-buttons-apply"
+          name="form.buttons.apply" type="submit" value="Apply">
         </div>
       </form>
     </body>
   </html>
 
+Let's modify the values:
 
   >>> request = TestRequest(form={'subobject.widgets.foofield':u'43',
   ...                             'subobject.widgets.barfield':u'55',
@@ -426,15 +460,26 @@
   ...                             'form.widgets.subobject-empty-marker':u'1',
   ...                             'form.buttons.apply':'Apply'})
 
+They are still the same:
+
+  >>> root['first'].subobject.foofield
+  66
+  >>> root['first'].subobject.barfield
+  99
+
   >>> editform.request = request
   >>> editform.update()
 
+Until we update the form:
+
   >>> root['first'].subobject.foofield
   43
-
   >>> root['first'].subobject.barfield
   55
 
+After the update the form says that the values got updated and renders the new
+values:
+
   >>> print editform.render()
   <html xmlns="http://www.w3.org/1999/xhtml">
     <body>
@@ -450,7 +495,9 @@
               </label>
             </div>
             <div class="widget">
-              <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="43">
+              <input class="text-widget required int-field"
+              id="subobject-widgets-foofield" name="subobject.widgets.foofield"
+              type="text" value="43">
             </div>
             <div class="label">
               <label for="subobject-widgets-barfield">
@@ -458,22 +505,27 @@
               </label>
             </div>
             <div class="widget">
-              <input class="text-widget int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="55">
+              <input class="text-widget int-field" id="subobject-widgets-barfield"
+              name="subobject.widgets.barfield" type="text" value="55">
             </div>
-            <input name="form.widgets.subobject-empty-marker" type="hidden" value="1">
+            <input name="form.widgets.subobject-empty-marker" type="hidden"
+            value="1">
           </div>
         </div>
         <div class="row">
           <label for="form-widgets-name">name</label>
-          <input class="text-widget required textline-field" id="form-widgets-name" name="form.widgets.name" type="text" value="first">
+          <input class="text-widget required textline-field" id="form-widgets-name"
+          name="form.widgets.name" type="text" value="first">
         </div>
         <div class="action">
-          <input class="submit-widget button-field" id="form-buttons-apply" name="form.buttons.apply" type="submit" value="Apply">
+          <input class="submit-widget button-field" id="form-buttons-apply"
+          name="form.buttons.apply" type="submit" value="Apply">
         </div>
       </form>
     </body>
   </html>
 
+Let's make a nasty error, by typing 'bad' instead of an integer:
 
   >>> request = TestRequest(form={'subobject.widgets.foofield':u'99',
   ...                             'subobject.widgets.barfield':u'bad',
@@ -482,10 +534,11 @@
   ...                             'form.buttons.apply':'Apply'})
 
   >>> editform.request = request
+  >>> editform.update()
 
-#>>> from pub.dbgpclient import brk; brk('192.168.32.1')
+Watch for the error message in the HTML:
+it has to appear at the field itself and at the top of the form:
 
-  >>> editform.update()
   >>> print editform.render()
   <html xmlns="http://www.w3.org/1999/xhtml">
     <body>
@@ -510,7 +563,9 @@
               </label>
             </div>
             <div class="widget">
-              <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="99">
+              <input class="text-widget required int-field"
+              id="subobject-widgets-foofield" name="subobject.widgets.foofield"
+              type="text" value="99">
             </div>
             <div class="label">
               <label for="subobject-widgets-barfield">
@@ -521,30 +576,36 @@
               <div class="error">The entered value is not a valid integer literal.</div>
             </div>
             <div class="widget">
-              <input class="text-widget int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="bad">
+              <input class="text-widget int-field" id="subobject-widgets-barfield"
+              name="subobject.widgets.barfield" type="text" value="bad">
             </div>
-            <input name="form.widgets.subobject-empty-marker" type="hidden" value="1">
+            <input name="form.widgets.subobject-empty-marker" type="hidden"
+            value="1">
           </div>
         </div>
         <div class="row">
           <label for="form-widgets-name">name</label>
-          <input class="text-widget required textline-field" id="form-widgets-name" name="form.widgets.name" type="text" value="first">
+          <input class="text-widget required textline-field" id="form-widgets-name"
+          name="form.widgets.name" type="text" value="first">
         </div>
         <div class="action">
-          <input class="submit-widget button-field" id="form-buttons-apply" name="form.buttons.apply" type="submit" value="Apply">
+          <input class="submit-widget button-field" id="form-buttons-apply"
+          name="form.buttons.apply" type="submit" value="Apply">
         </div>
       </form>
     </body>
   </html>
 
+The object values must stay at the old ones:
+
   >>> root['first'].subobject.foofield
   43
-
   >>> root['first'].subobject.barfield
   55
 
+Let's make more errors:
+Now we enter 'bad' and '999999', where '999999' hits the upper limit of the field.
 
-
   >>> request = TestRequest(form={'subobject.widgets.foofield':u'999999',
   ...                             'subobject.widgets.barfield':u'bad',
   ...                             'form.widgets.name':u'first',
@@ -552,10 +613,10 @@
   ...                             'form.buttons.apply':'Apply'})
 
   >>> editform.request = request
+  >>> editform.update()
 
-#>>> from pub.dbgpclient import brk; brk('192.168.32.1')
+Both errors must appear at the top of the form:
 
-  >>> editform.update()
   >>> print editform.render()
   <html xmlns="http://www.w3.org/1999/xhtml">
     <body>
@@ -585,7 +646,9 @@
               <div class="error">Value is too big</div>
             </div>
             <div class="widget">
-              <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="999999">
+              <input class="text-widget required int-field"
+              id="subobject-widgets-foofield" name="subobject.widgets.foofield"
+              type="text" value="999999">
             </div>
             <div class="label">
               <label for="subobject-widgets-barfield">
@@ -596,28 +659,36 @@
               <div class="error">The entered value is not a valid integer literal.</div>
             </div>
             <div class="widget">
-              <input class="text-widget int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="bad">
+              <input class="text-widget int-field" id="subobject-widgets-barfield"
+              name="subobject.widgets.barfield" type="text" value="bad">
             </div>
-            <input name="form.widgets.subobject-empty-marker" type="hidden" value="1">
+            <input name="form.widgets.subobject-empty-marker" type="hidden"
+            value="1">
           </div>
         </div>
         <div class="row">
           <label for="form-widgets-name">name</label>
-          <input class="text-widget required textline-field" id="form-widgets-name" name="form.widgets.name" type="text" value="first">
+          <input class="text-widget required textline-field" id="form-widgets-name"
+          name="form.widgets.name" type="text" value="first">
         </div>
         <div class="action">
-          <input class="submit-widget button-field" id="form-buttons-apply" name="form.buttons.apply" type="submit" value="Apply">
+          <input class="submit-widget button-field" id="form-buttons-apply"
+          name="form.buttons.apply" type="submit" value="Apply">
         </div>
       </form>
     </body>
   </html>
 
+And of course, the object values do not get modified:
+
   >>> root['first'].subobject.foofield
   43
-
   >>> root['first'].subobject.barfield
   55
 
+
+Simple but often used use-case is the display form:
+
   >>> editform = MyEditForm(root['first'], TestRequest())
   >>> addTemplate(editform)
   >>> editform.mode = interfaces.DISPLAY_MODE
@@ -636,7 +707,8 @@
               </label>
             </div>
             <div class="widget">
-              <span class="text-widget required int-field" id="subobject-widgets-foofield">43</span>
+              <span class="text-widget required int-field"
+              id="subobject-widgets-foofield">43</span>
             </div>
             <div class="label">
               <label for="subobject-widgets-barfield">
@@ -644,53 +716,20 @@
               </label>
             </div>
             <div class="widget">
-              <span class="text-widget int-field" id="subobject-widgets-barfield">55</span>
+              <span class="text-widget int-field"
+              id="subobject-widgets-barfield">55</span>
             </div>
           </div>
         </div>
         <div class="row">
           <label for="form-widgets-name">name</label>
-          <span class="text-widget required textline-field" id="form-widgets-name">first</span>
+          <span class="text-widget required textline-field"
+          id="form-widgets-name">first</span>
         </div>
         <div class="action">
-          <input class="submit-widget button-field" id="form-buttons-apply" name="form.buttons.apply" type="submit" value="Apply">
+          <input class="submit-widget button-field"
+          id="form-buttons-apply" name="form.buttons.apply" type="submit" value="Apply">
         </div>
       </form>
     </body>
   </html>
-
-
-
-
-
-#We define an interface containing a subobject, and an addform for it:
-#
-#  >>> from z3c.form import form, field
-#  >>> from z3c.form.dummy import MyComplexObject, IMyComplexObject
-#
-#Note, that creating an object will print some information about it:
-#
-#  >>> class MyAddForm(form.AddForm):
-#  ...     fields = field.Fields(IMyComplexObject)
-#  ...     def create(self, data):
-#  ...         print "MyAddForm.create", str(data)
-#  ...         return MyObject(**data)
-#  ...     def add(self, obj):
-#  ...         self.context[obj.name] = obj
-#  ...     def nextURL(self):
-#  ...         pass
-#
-#We create the form and try to update it:
-#
-#  >>> request = TestRequest()
-#  >>> myaddform =  MyAddForm(root, request)
-#
-##>>> from pub.dbgpclient import brk; brk('192.168.32.1')
-#
-#  >>> myaddform.update()
-#
-#  >>> addTemplate(myaddform)
-#
-#Now rendering the addform renders the subform as well:
-#
-#  >>> print myaddform.render()

Deleted: z3c.form/branches/adamg-objectwidget/src/z3c/form/dummy.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/dummy.py	2008-10-08 08:18:09 UTC (rev 91901)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/dummy.py	2008-10-08 09:30:09 UTC (rev 91902)
@@ -1,117 +0,0 @@
-############
-# REMOVE this after we found a good solution for factory
-
-
-import zope.interface
-import zope.schema
-from zope.schema.fieldproperty import FieldProperty
-
-class IMySubObject(zope.interface.Interface):
-    foofield = zope.schema.Int(
-        title=u"My foo field",
-        default=1111,
-        max=9999)
-    barfield = zope.schema.Int(
-        title=u"My dear bar",
-        default=2222,
-        required=False)
-
-class MySubObject(object):
-    zope.interface.implements(IMySubObject)
-
-    foofield = FieldProperty(IMySubObject['foofield'])
-    barfield = FieldProperty(IMySubObject['barfield'])
-
-class IMySecond(zope.interface.Interface):
-    subfield = zope.schema.Object(schema=IMySubObject)
-    moofield = zope.schema.TextLine(title=u"Something")
-
-class MySecond(object):
-    zope.interface.implements(IMySecond)
-
-    subfield = FieldProperty(IMySecond['subfield'])
-    moofield = FieldProperty(IMySecond['moofield'])
-
-
-class IMyObject(zope.interface.Interface):
-    subobject = zope.schema.Object(title=u'my object', schema=IMySubObject)
-    name = zope.schema.TextLine(title=u'name')
-
-class MyObject(object):
-    zope.interface.implements(IMyObject)
-    def __init__(self, name=u'', subobject=None):
-        self.subobject=subobject
-        self.name=name
-
-
-class IMyComplexObject(zope.interface.Interface):
-    subobject = zope.schema.Object(title=u'my object', schema=IMySecond)
-    name = zope.schema.TextLine(title=u'name')
-
-class MyComplexObject(object):
-    zope.interface.implements(IMyComplexObject)
-    def __init__(self, name=u'', subobject=None):
-        self.subobject=subobject
-        self.name=name
-
-import zope.interface
-import zope.component
-import zope.schema.interfaces
-
-from z3c.form import interfaces
-from z3c.form.object import IObjectFactory
-
-class FactoryAdapter(object):
-    """ """
-
-    zope.interface.implements(IObjectFactory)
-    zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
-        interfaces.IForm, interfaces.IWidget)
-
-    factory = None
-
-    def __init__(self, context, request, form, widget):
-        self.context = context
-        self.request = request
-        self.form = form
-        self.widget = widget
-
-    def get(self, value):
-        return self.factory()
-
-    def __repr__(self):
-        return '<%s %r>' % (self.__class__.__name__, self.__name__)
-
-#class MySubObjectFactory(FactoryAdapter):
-#    zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
-#        interfaces.IForm, zope.interface.Interface, interfaces.IWidget)
-#    #zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
-#    #    interfaces.IForm, zope.schema.interfaces.IObject, interfaces.IWidget)
-#
-#    factory = MySubObject
-#
-#class MySecondFactory(FactoryAdapter):
-#    zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
-#        interfaces.IForm, zope.interface.Interface, interfaces.IWidget)
-#    #zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
-#    #    interfaces.IForm, zope.schema.interfaces.IObject, interfaces.IWidget)
-#
-#    factory = MySecond
-
-class MySubObjectFactory(FactoryAdapter):
-    zope.component.adapts(
-        zope.interface.Interface, interfaces.IFormLayer,
-        interfaces.IForm, interfaces.IWidget)
-    #zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
-    #    interfaces.IForm, zope.schema.interfaces.IObject, interfaces.IWidget)
-
-    factory = MySubObject
-
-class MySecondFactory(FactoryAdapter):
-    zope.component.adapts(
-        zope.interface.Interface, interfaces.IFormLayer,
-        interfaces.IForm, interfaces.IWidget)
-    #zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
-    #    interfaces.IForm, zope.schema.interfaces.IObject, interfaces.IWidget)
-
-    factory = MySecond
\ No newline at end of file

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/interfaces.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/interfaces.py	2008-10-08 08:18:09 UTC (rev 91901)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/interfaces.py	2008-10-08 09:30:09 UTC (rev 91902)
@@ -156,7 +156,7 @@
 
 class IMultipleErrors(zope.interface.Interface):
     """An error that contains many errors"""
-    
+
     errors = zope.interface.Attribute("List of errors")
 
 # ----[ Fields ]--------------------------------------------------------------
@@ -325,6 +325,18 @@
         required=False)
 
 
+# ----[ Object factory ]-----------------------------------------------------
+
+class IObjectFactory(zope.interface.Interface):
+    """Factory that will instatiate our objects for ObjectWidget
+    It could also pre-populate properties as it gets the value passed
+    """
+
+    def get(value):
+        """return a default object created to be populated
+        """
+
+
 # ----[ Widgets ]------------------------------------------------------------
 
 class IWidget(ILocation):

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/object.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/object.py	2008-10-08 08:18:09 UTC (rev 91901)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/object.py	2008-10-08 09:30:09 UTC (rev 91902)
@@ -11,7 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Data Converters
+"""ObjectWidget related classes
 
 $Id$
 """
@@ -23,27 +23,14 @@
 
 from z3c.form.converter import BaseDataConverter
 
-from z3c.form.dummy import MySubObject
 from z3c.form import form, interfaces
 from z3c.form.field import Fields
 from z3c.form.error import MultipleErrors
 from z3c.form.i18n import MessageFactory as _
 
-class IObjectFactory(zope.interface.Interface):
-    """Factory that will instatiate our objects for ObjectWidget
-    """
-
-    def get(value):
-        """return a default object created to be populated
-        """
-
 class ObjectSubForm(form.BaseForm):
     zope.interface.implements(interfaces.ISubForm)
 
-    formErrorsMessage = _('There were some errors.')
-    successMessage = _('Data successfully updated.')
-    noChangesMessage = _('No changes were applied.')
-
     def __init__(self, context, parentWidget):
         self.context = context
         self.request = parentWidget.request
@@ -95,7 +82,6 @@
     zope.component.adapts(
         zope.schema.interfaces.IObject, interfaces.IObjectWidget)
 
-    #factory = MySubObject
     factory = None
 
     def _fields(self):
@@ -113,13 +99,17 @@
         #keep value passed, maybe some subclasses want it
 
         if self.factory is None:
+            name = self.field.schema.__module__+'.'+self.field.schema.__name__
             adapter = zope.component.queryMultiAdapter(
                 (self.widget.context, self.widget.request,
                  self.widget.form, self.widget),
-                IObjectFactory,
-                name=self.field.schema.__name__)
+                interfaces.IObjectFactory,
+                name=name)
             if adapter:
                 obj = adapter.get(value)
+            else:
+                raise ValueError("No IObjectFactory adapter registered for %s" %
+                                 name)
         else:
             #this is creepy, do we need this?
             #there seems to be no way to dispatch???
@@ -129,22 +119,42 @@
 
     def toFieldValue(self, value):
         """See interfaces.IDataConverter"""
-        if not value:
-            from pub.dbgpclient import brk; brk('192.168.32.1')
+        if value is interfaces.NOVALUE:
+            return self.field.missing_value
 
         if value[1]:
-            #lame, we must be able to show all errors
-            #if len(value[1])>1:
-            #    from pub.dbgpclient import brk; brk('192.168.32.1')
-
             raise MultipleErrors(value[1])
 
         obj = self.createObject(value)
 
         for name, f in self._fields().items():
-            try:
-                setattr(obj, name, value[0][name])
-            except KeyError:
-                #smells like an input error?
-                pass
+            setattr(obj, name, value[0][name])
         return obj
+
+class FactoryAdapter(object):
+    """Most basic-default factory adapter"""
+
+    zope.interface.implements(interfaces.IObjectFactory)
+    zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
+        interfaces.IForm, interfaces.IWidget)
+
+    factory = None
+
+    def __init__(self, context, request, form, widget):
+        self.context = context
+        self.request = request
+        self.form = form
+        self.widget = widget
+
+    def get(self, value):
+        return self.factory()
+
+    def __repr__(self):
+        return '<%s %r>' % (self.__class__.__name__, self.__name__)
+
+def registerFactoryAdapter(for_, klass):
+    """register the basic FactoryAdapter for a given interface and class"""
+    name = for_.__module__+'.'+for_.__name__
+    class temp(FactoryAdapter):
+        factory = klass
+    zope.component.provideAdapter(temp, name=name)
\ No newline at end of file

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/testing.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/testing.py	2008-10-08 08:18:09 UTC (rev 91901)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/testing.py	2008-10-08 09:30:09 UTC (rev 91902)
@@ -25,6 +25,7 @@
 import zope.component
 import zope.interface
 import zope.schema
+from zope.schema.fieldproperty import FieldProperty
 import zope.configuration.xmlconfig
 
 from zope.pagetemplate.interfaces import IPageTemplate
@@ -150,6 +151,65 @@
 def getPath(filename):
     return os.path.join(os.path.dirname(browser.__file__), filename)
 
+
+#############################
+# classes required by ObjectWidget tests
+#
+
+class IMySubObject(zope.interface.Interface):
+    foofield = zope.schema.Int(
+        title=u"My foo field",
+        default=1111,
+        max=9999)
+    barfield = zope.schema.Int(
+        title=u"My dear bar",
+        default=2222,
+        required=False)
+
+class MySubObject(object):
+    zope.interface.implements(IMySubObject)
+
+    foofield = FieldProperty(IMySubObject['foofield'])
+    barfield = FieldProperty(IMySubObject['barfield'])
+
+class IMySecond(zope.interface.Interface):
+    subfield = zope.schema.Object(
+        title=u"Second-subobject",
+        schema=IMySubObject)
+    moofield = zope.schema.TextLine(title=u"Something")
+
+class MySecond(object):
+    zope.interface.implements(IMySecond)
+
+    subfield = FieldProperty(IMySecond['subfield'])
+    moofield = FieldProperty(IMySecond['moofield'])
+
+
+class IMyObject(zope.interface.Interface):
+    subobject = zope.schema.Object(title=u'my object', schema=IMySubObject)
+    name = zope.schema.TextLine(title=u'name')
+
+class MyObject(object):
+    zope.interface.implements(IMyObject)
+    def __init__(self, name=u'', subobject=None):
+        self.subobject=subobject
+        self.name=name
+
+
+class IMyComplexObject(zope.interface.Interface):
+    subobject = zope.schema.Object(title=u'my object', schema=IMySecond)
+    name = zope.schema.TextLine(title=u'name')
+
+class MyComplexObject(object):
+    zope.interface.implements(IMyComplexObject)
+    def __init__(self, name=u'', subobject=None):
+        self.subobject=subobject
+        self.name=name
+
+#
+#
+#############################
+
 def setUp(test):
     test.globs = {'root': setup.placefulSetUp(True)}
 



More information about the Checkins mailing list