[Checkins] SVN: z3c.form/branches/adamg-objectwidget/src/z3c/form/ mostly checkpoint

Adam Groszer agroszer at gmail.com
Wed Oct 8 03:44:31 EDT 2008


Log message for revision 91900:
  mostly checkpoint
  multi-error solved
  cleaned up widget template
  

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
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object_display.pt
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object_input.pt
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/configure.zcml
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/dummy.py
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/error.py
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/field.py
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/object.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 07:43:01 UTC (rev 91899)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.py	2008-10-08 07:44:31 UTC (rev 91900)
@@ -14,8 +14,22 @@
 
     klass = u'object-widget'
     subform = None
+    _value = interfaces.NOVALUE
 
-    def _makeSubform(self):
+    #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__)
@@ -27,17 +41,29 @@
                 subobj = self.context
         self.subform = ObjectSubForm(subobj, self)
         #self.subform = ObjectSubForm(self.value, self)
+        self.subform.update()
 
     def update(self):
         super(ObjectWidget, self).update()
+        self.updateWidgets()
 
-        self._makeSubform()
-        self.subform.update()
+    #@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)
 
     def extract(self, default=interfaces.NOVALUE):
         if self.name+'-empty-marker' in self.request:
-            self._makeSubform()
-            self.subform.update()
+            self.updateWidgets()
             rv=self.subform.extractData()
             return rv
         else:

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 07:43:01 UTC (rev 91899)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.txt	2008-10-08 07:44:31 UTC (rev 91900)
@@ -26,7 +26,10 @@
   >>> zope.component.provideAdapter(MySubObjectFactory, name='IMySubObject')
   >>> zope.component.provideAdapter(MySecondFactory, name='IMySecond')
 
+  >>> from z3c.form.error import MultipleErrorViewSnippet
+  >>> zope.component.provideAdapter(MultipleErrorViewSnippet)
 
+
 As for all widgets, the objectwidget must provide the new ``IWidget``
 interface:
 
@@ -94,17 +97,32 @@
 
   >>> widget.update()
   >>> print widget.render()
-  <fieldset class="object-widget required" id="subobject" name="subobject">
-    <legend>my object widget</legend>
-    <input class="text-widget required int-field" id="subobject-widgets-foofield"
-           name="subobject.widgets.foofield" type="text" value="1,111">
-    <br>
-    <input class="text-widget required int-field" id="subobject-widgets-barfield"
-           name="subobject.widgets.barfield" type="text" value="2,222">
-    <br>
-    <input name="subobject-empty-marker" type="hidden" value="1">
-  </fieldset>
+  <html>
+    <body>
+      <div class="object-widget required">
+        <div class="label">
+          <label for="subobject-widgets-foofield">
+            <span>My foo field</span>
+            <span class="required">*</span>
+          </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">
+        </div>
+        <div class="label">
+          <label for="subobject-widgets-barfield">
+            <span>My dear bar</span>
+          </label>
+        </div>
+        <div class="widget">
+          <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>
+    </body>
+  </html>
 
+
 As you see all sort of default values are rendered.
 
 Let's provide a more meaningful value:
@@ -121,36 +139,64 @@
 
   >>> widget.update()
   >>> print widget.render()
-  <fieldset class="object-widget required" id="subobject" name="subobject">
-    <legend>my object widget</legend>
-    <input class="text-widget required int-field" id="subobject-widgets-foofield"
-           name="subobject.widgets.foofield" type="text" value="42">
-    <br>
-    <input class="text-widget required int-field" id="subobject-widgets-barfield"
-           name="subobject.widgets.barfield" type="text" value="666">
-    <br>
-    <input name="subobject-empty-marker" type="hidden" value="1">
-  </fieldset>
+  <html>
+    <body>
+      <div class="object-widget required">
+        <div class="label">
+          <label for="subobject-widgets-foofield">
+            <span>My foo field</span>
+            <span class="required">*</span>
+          </label>
+        </div>
+        <div class="widget">
+          <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">
+            <span>My dear bar</span>
+          </label>
+        </div>
+        <div class="widget">
+          <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>
+    </body>
+  </html>
 
-Let's fill in some values:
+Let's fill in some values via the request:
 
   >>> widget.request = TestRequest(form={'subobject.widgets.foofield':u'2',
   ...                                    'subobject.widgets.barfield':u'999'})
   >>> widget.update()
   >>> print widget.render()
-  <fieldset class="object-widget required" id="subobject" name="subobject">
-    <legend>my object widget</legend>
-    <input class="text-widget required int-field" id="subobject-widgets-foofield"
-           name="subobject.widgets.foofield" type="text" value="2">
-    <br>
-    <input class="text-widget required int-field" id="subobject-widgets-barfield"
-           name="subobject.widgets.barfield" type="text" value="999">
-    <br>
-    <input name="subobject-empty-marker" type="hidden" value="1">
-  </fieldset>
+  <html>
+    <body>
+      <div class="object-widget required">
+        <div class="label">
+          <label for="subobject-widgets-foofield">
+            <span>My foo field</span>
+            <span class="required">*</span>
+          </label>
+        </div>
+        <div class="widget">
+          <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">
+            <span>My dear bar</span>
+          </label>
+        </div>
+        <div class="widget">
+          <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>
+    </body>
+  </html>
 
 
-Error handling is next. Let's use teh value "bad" (an invalid integer literal)
+Error handling is next. Let's use the value "bad" (an invalid integer literal)
 as input for our internal (sub) widget.
 
   >>> widget.request = TestRequest(form={'subobject.widgets.foofield':u'2',
@@ -161,35 +207,45 @@
 
   >>> widget.update()
   >>> print widget.render()
-  <fieldset id="subobject" name="subobject"
-            class="object-widget required">
-  <legend>my object widget</legend>
-      <input id="subobject-widgets-foofield"
-             name="subobject.widgets.foofield"
-             class="text-widget required int-field" value="2"
-             type="text" />
-      <br />
-      <div class="error">
-    <div class="error">The entered value is not a valid integer literal.</div>
+  <html>
+    <body>
+      <div class="object-widget required">
+        <div class="label">
+          <label for="subobject-widgets-foofield">
+            <span>My foo field</span>
+            <span class="required">*</span>
+          </label>
+        </div>
+        <div class="widget">
+          <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">
+            <span>My dear bar</span>
+          </label>
+        </div>
+        <div class="error">
+          <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">
+        </div>
+        <input name="subobject-empty-marker" type="hidden" value="1">
       </div>
-      <input id="subobject-widgets-barfield"
-             name="subobject.widgets.barfield"
-             class="text-widget required int-field" value="bad"
-             type="text" />
-      <br />
-  <input name="subobject-empty-marker" type="hidden" value="1" />
-  </fieldset>
+    </body>
+  </html>
 
 
 
 
 
 
+In forms
+========
 
+Do all that fun in add and edit forms too:
 
 
-Do all that fun in add and edit forms too:
-
 We have to provide an adapter first:
 
   >>> zope.component.provideAdapter(object.ObjectFieldWidget)
@@ -201,6 +257,8 @@
   >>> from z3c.form import form, field
   >>> from z3c.form.dummy import MyObject, IMyObject
 
+Note, that creating an object will print some information about it:
+
   >>> class MyAddForm(form.AddForm):
   ...     fields = field.Fields(IMyObject)
   ...     def create(self, data):
@@ -220,18 +278,20 @@
 
   >>> myaddform.update()
 
-As usually, the form contains a widget manager with the expected widget
+As usual, the form contains a widget manager with the expected widget
 
   >>> myaddform.widgets.keys()
   ['subobject', 'name']
   >>> myaddform.widgets.values()
   [<ObjectWidget 'form.widgets.subobject'>, <TextWidget 'form.widgets.name'>]
 
-But now, the addform contains a subform, that the user didn't need to create
-and which is already updated:
+The addform has our ObjectWidget which in turn contains a subform:
 
   >>> myaddform.widgets['subobject'].subform
   <z3c.form.object.ObjectSubForm object at ...>
+
+Which in turn contains the sub-widgets:
+
   >>> myaddform.widgets['subobject'].subform.widgets.keys()
   ['foofield', 'barfield']
 
@@ -254,14 +314,26 @@
       <form action=".">
         <div class="row">
           <label for="form-widgets-subobject">my object</label>
-          <fieldset class="object-widget required" id="form-widgets-subobject" name="form.widgets.subobject">
-            <legend>my object</legend>
-            <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="1,111">
-            <br>
-            <input class="text-widget required int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="2,222">
-            <br>
+          <div class="object-widget required">
+            <div class="label">
+              <label for="subobject-widgets-foofield">
+                <span>My foo field</span>
+                <span class="required">*</span>
+              </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">
+            </div>
+            <div class="label">
+              <label for="subobject-widgets-barfield">
+                <span>My dear bar</span>
+              </label>
+            </div>
+            <div class="widget">
+              <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">
-          </fieldset>
+          </div>
         </div>
         <div class="row">
           <label for="form-widgets-name">name</label>
@@ -300,11 +372,8 @@
   >>> root['first'].subobject.barfield
   99
 
-  >>> myaddform.render()
-  ''
 
 
-
   >>> class MyEditForm(form.EditForm):
   ...     fields = field.Fields(IMyObject)
 
@@ -318,14 +387,26 @@
       <form action=".">
         <div class="row">
           <label for="form-widgets-subobject">my object</label>
-          <fieldset class="object-widget required" id="form-widgets-subobject" name="form.widgets.subobject">
-            <legend>my object</legend>
-            <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="66">
-            <br>
-            <input class="text-widget required int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="99">
-            <br>
+          <div class="object-widget required">
+            <div class="label">
+              <label for="subobject-widgets-foofield">
+                <span>My foo field</span>
+                <span class="required">*</span>
+              </label>
+            </div>
+            <div class="widget">
+              <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">
+                <span>My dear bar</span>
+              </label>
+            </div>
+            <div class="widget">
+              <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">
-          </fieldset>
+          </div>
         </div>
         <div class="row">
           <label for="form-widgets-name">name</label>
@@ -361,14 +442,26 @@
       <form action=".">
         <div class="row">
           <label for="form-widgets-subobject">my object</label>
-          <fieldset class="object-widget required" id="form-widgets-subobject" name="form.widgets.subobject">
-            <legend>my object</legend>
-            <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="43">
-            <br>
-            <input class="text-widget required int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="55">
-            <br>
+          <div class="object-widget required">
+            <div class="label">
+              <label for="subobject-widgets-foofield">
+                <span>My foo field</span>
+                <span class="required">*</span>
+              </label>
+            </div>
+            <div class="widget">
+              <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">
+                <span>My dear bar</span>
+              </label>
+            </div>
+            <div class="widget">
+              <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">
-          </fieldset>
+          </div>
         </div>
         <div class="row">
           <label for="form-widgets-name">name</label>
@@ -409,17 +502,29 @@
             <div class="error">The entered value is not a valid integer literal.</div>
           </b>
           <label for="form-widgets-subobject">my object</label>
-          <fieldset class="object-widget required" id="form-widgets-subobject" name="form.widgets.subobject">
-            <legend>my object</legend>
-            <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="99">
-            <br>
+          <div class="object-widget required">
+            <div class="label">
+              <label for="subobject-widgets-foofield">
+                <span>My foo field</span>
+                <span class="required">*</span>
+              </label>
+            </div>
+            <div class="widget">
+              <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">
+                <span>My dear bar</span>
+              </label>
+            </div>
             <div class="error">
               <div class="error">The entered value is not a valid integer literal.</div>
             </div>
-            <input class="text-widget required int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="bad">
-            <br>
+            <div class="widget">
+              <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">
-          </fieldset>
+          </div>
         </div>
         <div class="row">
           <label for="form-widgets-name">name</label>
@@ -458,26 +563,43 @@
       <ul>
         <li>
         my object:
+          <div class="error">Value is too big</div>
           <div class="error">The entered value is not a valid integer literal.</div>
         </li>
       </ul>
       <form action=".">
         <div class="row">
           <b>
+            <div class="error">Value is too big</div>
             <div class="error">The entered value is not a valid integer literal.</div>
           </b>
           <label for="form-widgets-subobject">my object</label>
-          <fieldset class="object-widget required" id="form-widgets-subobject" name="form.widgets.subobject">
-            <legend>my object</legend>
-            <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="badder">
-            <br>
+          <div class="object-widget required">
+            <div class="label">
+              <label for="subobject-widgets-foofield">
+                <span>My foo field</span>
+                <span class="required">*</span>
+              </label>
+            </div>
             <div class="error">
+              <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">
+            </div>
+            <div class="label">
+              <label for="subobject-widgets-barfield">
+                <span>My dear bar</span>
+              </label>
+            </div>
+            <div class="error">
               <div class="error">The entered value is not a valid integer literal.</div>
             </div>
-            <input class="text-widget required int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="bad">
-            <br>
+            <div class="widget">
+              <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">
-          </fieldset>
+          </div>
         </div>
         <div class="row">
           <label for="form-widgets-name">name</label>
@@ -495,3 +617,80 @@
 
   >>> root['first'].subobject.barfield
   55
+
+  >>> editform = MyEditForm(root['first'], TestRequest())
+  >>> addTemplate(editform)
+  >>> editform.mode = interfaces.DISPLAY_MODE
+  >>> editform.update()
+  >>> print editform.render()
+  <html xmlns="http://www.w3.org/1999/xhtml">
+    <body>
+      <form action=".">
+        <div class="row">
+          <label for="form-widgets-subobject">my object</label>
+          <div class="object-widget required">
+            <div class="label">
+              <label for="subobject-widgets-foofield">
+                <span>My foo field</span>
+                <span class="required">*</span>
+              </label>
+            </div>
+            <div class="widget">
+              <span class="text-widget required int-field" id="subobject-widgets-foofield">43</span>
+            </div>
+            <div class="label">
+              <label for="subobject-widgets-barfield">
+                <span>My dear bar</span>
+              </label>
+            </div>
+            <div class="widget">
+              <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>
+        </div>
+        <div class="action">
+          <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()

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object_display.pt
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object_display.pt	2008-10-08 07:43:01 UTC (rev 91899)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object_display.pt	2008-10-08 07:44:31 UTC (rev 91900)
@@ -1,30 +1,16 @@
-<fieldset id="" name="" class="" title="" lang="" disabled=""
-       tal:attributes="id view/id;
-                       name view/name;
-                       class view/klass;
-                       style view/style;
-                       title view/title;
-                       lang view/lang;
-                       onclick view/onclick;
-                       ondblclick view/ondblclick;
-                       onmousedown view/onmousedown;
-                       onmouseup view/onmouseup;
-                       onmouseover view/onmouseover;
-                       onmousemove view/onmousemove;
-                       onmouseout view/onmouseout;
-                       onkeypress view/onkeypress;
-                       onkeydown view/onkeydown;
-                       onkeyup view/onkeyup;
-                       disabled view/disabled;
-                       tabindex view/tabindex;
-                       onfocus view/onfocus;
-                       onblur view/onblur;
-                       onchange view/onchange;">
-<legend tal:content="view/label">foobar</legend>
-
-<tal:block repeat="widget view/subform/widgets/values">
-    <tal:block content="structure widget/render" />
-    <br/>
-</tal:block>
-
-</fieldset>
\ No newline at end of file
+<div class="object-widget"
+     tal:attributes="class view/klass">
+    <tal:block repeat="widget view/subform/widgets/values">
+        <div class="label">
+          <label tal:attributes="for widget/id">
+            <span i18n:translate=""
+                tal:content="widget/label">label</span>
+            <span class="required"
+                  tal:condition="widget/required">*</span>
+          </label>
+        </div>
+        <div class="widget" tal:content="structure widget/render">
+          <input type="text" size="24" value="" />
+        </div>
+    </tal:block>
+</div>
\ No newline at end of file

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object_input.pt
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object_input.pt	2008-10-08 07:43:01 UTC (rev 91899)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object_input.pt	2008-10-08 07:44:31 UTC (rev 91900)
@@ -1,37 +1,22 @@
-<fieldset id="" name="" class="" title="" lang="" disabled=""
-       tal:attributes="id view/id;
-                       name view/name;
-                       class view/klass;
-                       style view/style;
-                       title view/title;
-                       lang view/lang;
-                       onclick view/onclick;
-                       ondblclick view/ondblclick;
-                       onmousedown view/onmousedown;
-                       onmouseup view/onmouseup;
-                       onmouseover view/onmouseover;
-                       onmousemove view/onmousemove;
-                       onmouseout view/onmouseout;
-                       onkeypress view/onkeypress;
-                       onkeydown view/onkeydown;
-                       onkeyup view/onkeyup;
-                       disabled view/disabled;
-                       tabindex view/tabindex;
-                       onfocus view/onfocus;
-                       onblur view/onblur;
-                       onchange view/onchange;">
-<legend tal:content="view/label">foobar</legend>
-
-<tal:block repeat="widget view/subform/widgets/values">
-    <div class="error"
-         tal:condition="widget/error">
-      <span tal:replace="structure widget/error/render">error</span>
-    </div>
-    <tal:block content="structure widget/render" />
-    <br/>
-</tal:block>
-
-<input name="field-empty-marker" type="hidden" value="1"
-       tal:attributes="name string:${view/name}-empty-marker" />
-
-</fieldset>
\ No newline at end of file
+<div class="object-widget"
+     tal:attributes="class view/klass">
+    <tal:block repeat="widget view/subform/widgets/values">
+        <div class="label">
+          <label tal:attributes="for widget/id">
+            <span i18n:translate=""
+                tal:content="widget/label">label</span>
+            <span class="required"
+                  tal:condition="widget/required">*</span>
+          </label>
+        </div>
+        <div class="error"
+             tal:condition="widget/error">
+          <span tal:replace="structure widget/error/render">error</span>
+        </div>
+        <div class="widget" tal:content="structure widget/render">
+          <input type="text" size="24" value="" />
+        </div>
+    </tal:block>
+    <input name="field-empty-marker" type="hidden" value="1"
+           tal:attributes="name string:${view/name}-empty-marker" />
+</div>
\ No newline at end of file

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/configure.zcml
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/configure.zcml	2008-10-08 07:43:01 UTC (rev 91899)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/configure.zcml	2008-10-08 07:44:31 UTC (rev 91900)
@@ -125,6 +125,11 @@
       permission="zope.Public"
       />
   <adapter
+      factory=".error.MultipleErrorViewSnippet"
+      trusted="True"
+      permission="zope.Public"
+      />
+  <adapter
       factory=".error.StandardErrorViewTemplate"
       />
 

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/dummy.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/dummy.py	2008-10-08 07:43:01 UTC (rev 91899)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/dummy.py	2008-10-08 07:44:31 UTC (rev 91900)
@@ -7,9 +7,14 @@
 from zope.schema.fieldproperty import FieldProperty
 
 class IMySubObject(zope.interface.Interface):
-    foofield = zope.schema.Int(default=1111,
-                               max=9999)
-    barfield = zope.schema.Int(default=2222)
+    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)
@@ -39,6 +44,16 @@
         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

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/error.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/error.py	2008-10-08 07:43:01 UTC (rev 91899)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/error.py	2008-10-08 07:44:31 UTC (rev 91900)
@@ -107,17 +107,20 @@
         interfaces.IMultipleErrors, None, None, None, None, None)
 
     def update(self):
-        output = ''
-        for error in self.error.errors:
-            view = zope.component.getMultiAdapter(
-                (error, self.request, widget, widget.field,
-                 self.form, self.content), interfaces.IErrorViewSnippet)
-            output += view.render()
-        self.output = output
+        pass
 
     def render(self):
-        return self.output
+        return ''.join([view.render() for view in self.error.errors])
 
+
+class MultipleErrors(Exception):
+    zope.interface.implements(interfaces.IMultipleErrors)
+    """An error that contains many errors"""
+
+    def __init__(self, errors):
+        self.errors = errors
+
+
 class ErrorViewTemplateFactory(object):
     """Error view template factory."""
 

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/field.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/field.py	2008-10-08 07:43:01 UTC (rev 91899)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/field.py	2008-10-08 07:44:31 UTC (rev 91900)
@@ -22,6 +22,7 @@
 import zope.schema.interfaces
 
 from z3c.form import interfaces, util
+from z3c.form.error import MultipleErrors
 from z3c.form.widget import AfterWidgetUpdateEvent
 
 
@@ -283,7 +284,8 @@
                      getattr(widget, 'field', None),
                      widget),
                     interfaces.IValidator).validate(value)
-            except (zope.schema.ValidationError, ValueError), error:
+            except (zope.schema.ValidationError,
+                    ValueError, MultipleErrors), error:
                 view = zope.component.getMultiAdapter(
                     (error, self.request, widget, widget.field,
                      self.form, self.content), interfaces.IErrorViewSnippet)

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/object.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/object.py	2008-10-08 07:43:01 UTC (rev 91899)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/object.py	2008-10-08 07:44:31 UTC (rev 91900)
@@ -26,6 +26,7 @@
 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):
@@ -128,12 +129,15 @@
 
     def toFieldValue(self, value):
         """See interfaces.IDataConverter"""
+        if not value:
+            from pub.dbgpclient import brk; brk('192.168.32.1')
+
         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 value[1][0].error
+            raise MultipleErrors(value[1])
 
         obj = self.createObject(value)
 



More information about the Checkins mailing list