[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