[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