[Checkins] SVN: z3c.form/trunk/ Make add/remove buttons of MultiWidget conditional based on field's min/max length. Add more TODOs for MultiWidget.
Dan Korostelev
nadako at gmail.com
Tue Feb 3 20:13:03 EST 2009
Log message for revision 96053:
Make add/remove buttons of MultiWidget conditional based on field's min/max length. Add more TODOs for MultiWidget.
Relabeled MultiWidget's remove button from "Remove" to "Remove selected" to avoid confusion.
Re-enabled tests for z3c.pt. However, it seems that there's a strange bug with macros that I don't understand in z3c.pt. See tests/simple_groupedit.pt for more comments.
Changed:
U z3c.form/trunk/TODOS.txt
U z3c.form/trunk/src/z3c/form/browser/README.txt
U z3c.form/trunk/src/z3c/form/browser/multi.py
U z3c.form/trunk/src/z3c/form/browser/multi.txt
U z3c.form/trunk/src/z3c/form/browser/objectmulti.txt
U z3c.form/trunk/src/z3c/form/locales/de/LC_MESSAGES/z3c.form.po
U z3c.form/trunk/src/z3c/form/locales/fr/LC_MESSAGES/z3c.form.po
U z3c.form/trunk/src/z3c/form/locales/ru/LC_MESSAGES/z3c.form.mo
U z3c.form/trunk/src/z3c/form/locales/ru/LC_MESSAGES/z3c.form.po
U z3c.form/trunk/src/z3c/form/locales/z3c.form.pot
U z3c.form/trunk/src/z3c/form/locales/zh_CN/LC_MESSAGES/z3c.form.po
U z3c.form/trunk/src/z3c/form/tests/simple_groupedit.pt
U z3c.form/trunk/src/z3c/form/tests/test_doc.py
U z3c.form/trunk/src/z3c/form/widget.py
U z3c.form/trunk/src/z3c/form/widget.txt
-=-
Modified: z3c.form/trunk/TODOS.txt
===================================================================
--- z3c.form/trunk/TODOS.txt 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/TODOS.txt 2009-02-04 01:13:03 UTC (rev 96053)
@@ -9,6 +9,18 @@
and ``ISelectWidget``. We have to define more hidden widgets.
+Widgets
+-------
+
+- The MultiWidget should render a minimum number of elements by default
+ if the field defines min_length. Also, if user tries to remove elements
+ so the number of widgets becomes less than minimum - the widget should
+ add widgets to make their number minimum again. (Did you understand
+ this?:))
+
+- The MultiWidget should provide a way to reorder elements if used
+ for the ISequence field.
+
Documentation
-------------
Modified: z3c.form/trunk/src/z3c/form/browser/README.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/README.txt 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/src/z3c/form/browser/README.txt 2009-02-04 01:13:03 UTC (rev 96053)
@@ -609,7 +609,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -678,7 +678,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -814,7 +814,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -884,7 +884,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -952,7 +952,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -1021,7 +1021,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -1089,7 +1089,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -1158,7 +1158,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -1225,7 +1225,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -1292,7 +1292,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -1359,7 +1359,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -1428,7 +1428,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -1497,7 +1497,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -1564,7 +1564,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -1633,7 +1633,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -1702,7 +1702,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -1944,7 +1944,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2013,7 +2013,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2149,7 +2149,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2219,7 +2219,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2287,7 +2287,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2356,7 +2356,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2424,7 +2424,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2493,7 +2493,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2560,7 +2560,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2627,7 +2627,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2694,7 +2694,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2763,7 +2763,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2832,7 +2832,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2899,7 +2899,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -2968,7 +2968,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
@@ -3037,7 +3037,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="bar-buttons-remove"
name="bar.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="bar.count" value="2" />
Modified: z3c.form/trunk/src/z3c/form/browser/multi.py
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/multi.py 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/src/z3c/form/browser/multi.py 2009-02-04 01:13:03 UTC (rev 96053)
@@ -16,6 +16,8 @@
$Id: select.py 78513 2007-07-31 23:03:47Z srichter $
"""
__docformat__ = "reStructuredText"
+from operator import attrgetter
+
import zope.component
import zope.interface
import zope.schema
@@ -44,6 +46,7 @@
items = ()
def updateActions(self):
+ self.updateAllowAddRemove()
if self.name is not None:
self.prefix = self.name
self.actions = zope.component.getMultiAdapter(
@@ -52,15 +55,18 @@
def update(self):
"""See z3c.form.interfaces.IWidget."""
+ super(MultiWidget, self).update()
self.updateActions()
- super(MultiWidget, self).update()
self.actions.execute()
+ self.updateActions() # Update again, as conditions may change
- @button.buttonAndHandler(_('Add'), name='add')
+ @button.buttonAndHandler(_('Add'), name='add',
+ condition=attrgetter('allowAdding'))
def handleAdd(self, action):
self.appendAddingWidget()
- @button.buttonAndHandler(_('Remove'), name='remove')
+ @button.buttonAndHandler(_('Remove selected'), name='remove',
+ condition=attrgetter('allowRemoving'))
def handleRemove(self, action):
self.widgets = [widget for widget in self.widgets
if ('%s.remove' % (widget.name)) not in self.request]
Modified: z3c.form/trunk/src/z3c/form/browser/multi.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/multi.txt 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/src/z3c/form/browser/multi.txt 2009-02-04 01:13:03 UTC (rev 96053)
@@ -63,7 +63,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="widget-name-buttons-remove"
name="widget.name.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="widget.name.count" value="0" />
@@ -93,7 +93,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="widget-name-buttons-remove"
name="widget.name.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="widget.name.count" value="0" />
@@ -113,9 +113,6 @@
<input type="submit" id="widget-name-buttons-add"
name="widget.name.buttons.add"
class="submit-widget button-field" value="Add" />
- <input type="submit" id="widget-name-buttons-remove"
- name="widget.name.buttons.remove"
- class="submit-widget button-field" value="Remove" />
</div>
</div>
<input type="hidden" name="widget.name.count" value="0" />
@@ -131,8 +128,8 @@
>>> zope.component.provideAdapter(FieldWidgetDataConverter)
>>> zope.component.provideAdapter(SimpleFieldValidator)
+ >>> widget.value = [u'42', u'43']
>>> widget.update()
- >>> widget.value = [u'42', u'43']
>>> print widget.render()
<div class="multi-widget">
<div id="widget-id-0-row" class="row">
@@ -181,7 +178,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="widget-name-buttons-remove"
name="widget.name.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="widget.name.count" value="2" />
@@ -266,7 +263,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="widget-name-buttons-remove"
name="widget.name.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="widget.name.count" value="3" />
@@ -350,12 +347,12 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="widget-name-buttons-remove"
name="widget.name.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="widget.name.count" value="3" />
-As you can see in the above sample, the new stored value gest rendered as a
+As you can see in the above sample, the new stored value get rendered as a
real value and the new adding value input field is gone. Now let's try to
remove an existing value:
@@ -364,10 +361,10 @@
... 'widget.name.1':u'43',
... 'widget.name.2':u'44',
... 'widget.name.1.remove':u'1',
- ... 'widget.name.buttons.remove':'Remove'})
+ ... 'widget.name.buttons.remove':'Remove selected'})
>>> widget.update()
-This is good so, because the Remove is an widget-internal submit action
+This is good so, because the Remove selected is an widget-internal submit action
>>> widget.extract()
[u'42', u'43', u'44']
@@ -420,7 +417,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="widget-name-buttons-remove"
name="widget.name.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="widget.name.count" value="2" />
@@ -476,7 +473,7 @@
<input id="widget-name-buttons-add" name="widget.name.buttons.add"
class="submit-widget button-field" value="Add" type="submit" />
<input id="widget-name-buttons-remove" name="widget.name.buttons.remove"
- class="submit-widget button-field" value="Remove" type="submit" />
+ class="submit-widget button-field" value="Remove selected" type="submit" />
</div>
</div>
<input type="hidden" name="widget.name.count" value="2" />
@@ -549,13 +546,199 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="widget-name-buttons-remove"
name="widget.name.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="widget.name.count" value="2" />
+The widget filters out the add and remove buttons depending on the
+current value and the field constraints. You already saw that there's
+no remove button for empty value. Now, let's check rendering with
+minimum and maximum lengths defined in the field constraints.
+ >>> field = zope.schema.List(
+ ... __name__=u'foo',
+ ... value_type=zope.schema.Int(title=u'Number'),
+ ... min_length=1,
+ ... max_length=3
+ ... )
+ >>> widget.field = field
+ >>> widget.widgets = []
+ >>> widget.value = []
+Let's test with minimum sequence, there should be no remove button:
+
+ >>> widget.request = TestRequest(form={'widget.name.count':u'1',
+ ... 'widget.name.0':u'42'})
+ >>> widget.update()
+ >>> print widget.render()
+ <div class="multi-widget">
+ <div id="widget-id-0-row" class="row">
+ <div class="label">
+ <label for="widget-id-0">
+ <span>Number</span>
+ <span class="required">*</span>
+ </label>
+ </div>
+ <div class="widget">
+ <div class="multi-widget-checkbox">
+ <input type="checkbox" value="1"
+ class="multi-widget-checkbox checkbox-widget"
+ id="widget-id-0-remove"
+ name="widget.name.0.remove" />
+ </div>
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-0" name="widget.name.0"
+ class="text-widget required int-field" value="42" />
+ </div>
+ </div>
+ </div>
+ <div class="buttons">
+ <input type="submit" id="widget-name-buttons-add"
+ name="widget.name.buttons.add"
+ class="submit-widget button-field" value="Add" />
+ </div>
+ </div>
+ <input type="hidden" name="widget.name.count" value="1" />
+
+Now, with middle-length sequence. All buttons should be there.
+
+ >>> widget.request = TestRequest(form={'widget.name.count':u'2',
+ ... 'widget.name.0':u'42',
+ ... 'widget.name.1':u'43'})
+ >>> widget.update()
+ >>> print widget.render()
+ <div class="multi-widget">
+ <div id="widget-id-0-row" class="row">
+ <div class="label">
+ <label for="widget-id-0">
+ <span>Number</span>
+ <span class="required">*</span>
+ </label>
+ </div>
+ <div class="widget">
+ <div class="multi-widget-checkbox">
+ <input type="checkbox" value="1"
+ class="multi-widget-checkbox checkbox-widget"
+ id="widget-id-0-remove"
+ name="widget.name.0.remove" />
+ </div>
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-0" name="widget.name.0"
+ class="text-widget required int-field" value="42" />
+ </div>
+ </div>
+ </div>
+ <div id="widget-id-1-row" class="row">
+ <div class="label">
+ <label for="widget-id-1">
+ <span>Number</span>
+ <span class="required">*</span>
+ </label>
+ </div>
+ <div class="widget">
+ <div class="multi-widget-checkbox">
+ <input type="checkbox" value="1"
+ class="multi-widget-checkbox checkbox-widget"
+ id="widget-id-1-remove"
+ name="widget.name.1.remove" />
+ </div>
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-1" name="widget.name.1"
+ class="text-widget required int-field" value="43" />
+ </div>
+ </div>
+ </div>
+ <div class="buttons">
+ <input type="submit" id="widget-name-buttons-add"
+ name="widget.name.buttons.add"
+ class="submit-widget button-field" value="Add" />
+ <input type="submit" id="widget-name-buttons-remove"
+ name="widget.name.buttons.remove"
+ class="submit-widget button-field" value="Remove selected" />
+ </div>
+ </div>
+ <input type="hidden" name="widget.name.count" value="2" />
+
+Okay, now let's check the maximum-length sequence. There should be
+no add button:
+
+ >>> widget.request = TestRequest(form={'widget.name.count':u'3',
+ ... 'widget.name.0':u'42',
+ ... 'widget.name.1':u'43',
+ ... 'widget.name.2':u'44'})
+ >>> widget.update()
+ >>> print widget.render()
+ <div class="multi-widget">
+ <div id="widget-id-0-row" class="row">
+ <div class="label">
+ <label for="widget-id-0">
+ <span>Number</span>
+ <span class="required">*</span>
+ </label>
+ </div>
+ <div class="widget">
+ <div class="multi-widget-checkbox">
+ <input type="checkbox" value="1"
+ class="multi-widget-checkbox checkbox-widget"
+ id="widget-id-0-remove"
+ name="widget.name.0.remove" />
+ </div>
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-0" name="widget.name.0"
+ class="text-widget required int-field" value="42" />
+ </div>
+ </div>
+ </div>
+ <div id="widget-id-1-row" class="row">
+ <div class="label">
+ <label for="widget-id-1">
+ <span>Number</span>
+ <span class="required">*</span>
+ </label>
+ </div>
+ <div class="widget">
+ <div class="multi-widget-checkbox">
+ <input type="checkbox" value="1"
+ class="multi-widget-checkbox checkbox-widget"
+ id="widget-id-1-remove"
+ name="widget.name.1.remove" />
+ </div>
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-1" name="widget.name.1"
+ class="text-widget required int-field" value="43" />
+ </div>
+ </div>
+ </div>
+ <div id="widget-id-2-row" class="row">
+ <div class="label">
+ <label for="widget-id-2">
+ <span>Number</span>
+ <span class="required">*</span>
+ </label>
+ </div>
+ <div class="widget">
+ <div class="multi-widget-checkbox">
+ <input type="checkbox" value="1"
+ class="multi-widget-checkbox checkbox-widget"
+ id="widget-id-2-remove"
+ name="widget.name.2.remove" />
+ </div>
+ <div class="multi-widget-input"><input
+ type="text" id="widget-id-2" name="widget.name.2"
+ class="text-widget required int-field" value="44" />
+ </div>
+ </div>
+ </div>
+ <div class="buttons">
+ <input type="submit" id="widget-name-buttons-remove"
+ name="widget.name.buttons.remove"
+ class="submit-widget button-field" value="Remove selected" />
+ </div>
+ </div>
+ <input type="hidden" name="widget.name.count" value="3" />
+
+
Displaying
----------
@@ -786,7 +969,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="widget-buttons-remove"
name="widget.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="None.count" value="2" />
Modified: z3c.form/trunk/src/z3c/form/browser/objectmulti.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/objectmulti.txt 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/src/z3c/form/browser/objectmulti.txt 2009-02-04 01:13:03 UTC (rev 96053)
@@ -70,7 +70,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="widget-name-buttons-remove"
name="widget.name.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="widget.name.count" value="0" />
@@ -100,7 +100,7 @@
class="submit-widget button-field" value="Add" />
<input type="submit" id="widget-name-buttons-remove"
name="widget.name.buttons.remove"
- class="submit-widget button-field" value="Remove" />
+ class="submit-widget button-field" value="Remove selected" />
</div>
</div>
<input type="hidden" name="widget.name.count" value="0" />
@@ -130,9 +130,6 @@
<input type="submit" id="foo-buttons-add"
name="foo.buttons.add"
class="submit-widget button-field" value="Add" />
- <input type="submit" id="foo-buttons-remove"
- name="foo.buttons.remove"
- class="submit-widget button-field" value="Remove" />
</div>
</div>
<input type="hidden" name="foo.count" value="0" />
@@ -184,6 +181,7 @@
just cry about it in the HTML:
>>> widget.value = [{'foofield': None, 'barfield': 666}]
+ >>> widget.update()
>>> print widget.render()
<div class="multi-widget required">
<div id="foo-0-row" class="row">
@@ -234,7 +232,7 @@
<input id="foo-buttons-add" name="foo.buttons.add"
class="submit-widget button-field" value="Add" type="submit" />
<input id="foo-buttons-remove" name="foo.buttons.remove"
- class="submit-widget button-field" value="Remove" type="submit" />
+ class="submit-widget button-field" value="Remove selected" type="submit" />
</div>
</div>
<input type="hidden" name="foo.count" value="1" />
@@ -342,7 +340,7 @@
type="submit" />
<input id="foo-buttons-remove"
name="foo.buttons.remove"
- class="submit-widget button-field" value="Remove"
+ class="submit-widget button-field" value="Remove selected"
type="submit" />
</div>
</div>
@@ -505,7 +503,7 @@
type="submit" />
<input id="foo-buttons-remove"
name="foo.buttons.remove"
- class="submit-widget button-field" value="Remove"
+ class="submit-widget button-field" value="Remove selected"
type="submit" />
</div>
</div>
@@ -667,7 +665,7 @@
<input class="submit-widget button-field" id="foo-buttons-add"
name="foo.buttons.add" type="submit" value="Add">
<input class="submit-widget button-field" id="foo-buttons-remove"
- name="foo.buttons.remove" type="submit" value="Remove">
+ name="foo.buttons.remove" type="submit" value="Remove selected">
</div>
</div>
<input name="foo.count" type="hidden" value="3">
@@ -707,7 +705,7 @@
... 'foo.2.widgets.barfield':u'98',
... 'foo.2-empty-marker':u'1',
... 'foo.1.remove':u'1',
- ... 'foo.buttons.remove':'Remove'})
+ ... 'foo.buttons.remove':'Remove selected'})
>>> widget.update()
>>> print widget.render()
<div class="multi-widget required">
@@ -793,13 +791,13 @@
<input class="submit-widget button-field" id="foo-buttons-add"
name="foo.buttons.add" type="submit" value="Add">
<input class="submit-widget button-field" id="foo-buttons-remove"
- name="foo.buttons.remove" type="submit" value="Remove">
+ name="foo.buttons.remove" type="submit" value="Remove selected">
</div>
</div>
<input name="foo.count" type="hidden" value="2">
Let's see what we get on value extraction:
-(this is good so, because Remove is a widget-internal submit)
+(this is good so, because Remove selected is a widget-internal submit)
>>> value = widget.extract()
>>> value
@@ -917,7 +915,7 @@
</div>
<div class="buttons">
<input class="submit-widget button-field" id="foo-buttons-add" name="foo.buttons.add" type="submit" value="Add">
- <input class="submit-widget button-field" id="foo-buttons-remove" name="foo.buttons.remove" type="submit" value="Remove">
+ <input class="submit-widget button-field" id="foo-buttons-remove" name="foo.buttons.remove" type="submit" value="Remove selected">
</div>
</div>
<input name="foo.count" type="hidden" value="2">
@@ -1013,7 +1011,7 @@
</div>
<div class="buttons">
<input class="submit-widget button-field" id="foo-buttons-add" name="foo.buttons.add" type="submit" value="Add">
- <input class="submit-widget button-field" id="foo-buttons-remove" name="foo.buttons.remove" type="submit" value="Remove">
+ <input class="submit-widget button-field" id="foo-buttons-remove" name="foo.buttons.remove" type="submit" value="Remove selected">
</div>
</div>
<input name="foo.count" type="hidden" value="2">
\ No newline at end of file
Modified: z3c.form/trunk/src/z3c/form/locales/de/LC_MESSAGES/z3c.form.po
===================================================================
--- z3c.form/trunk/src/z3c/form/locales/de/LC_MESSAGES/z3c.form.po 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/src/z3c/form/locales/de/LC_MESSAGES/z3c.form.po 2009-02-04 01:13:03 UTC (rev 96053)
@@ -12,7 +12,7 @@
msgstr ""
"Project-Id-Version: Development/Unknown\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: Tue Feb 3 23:21:02 2009\n"
+"POT-Creation-Date: Wed Feb 4 04:06:37 2009\n"
"PO-Revision-Date: 2008-09-08 08:27+0100\n"
"Last-Translator: Hermann Himmelbauer <dusty at qwer.tk>\n"
"Language-Team: Zope 3 Developers <zope3-dev at zope.org>\n"
@@ -20,13 +20,13 @@
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: src/z3c/form/browser/multi.py:59 src/z3c/form/form.py:209
+#: src/z3c/form/browser/multi.py:63 src/z3c/form/form.py:209
msgid "Add"
msgstr "Hinzufügen"
-#: src/z3c/form/browser/multi.py:63
-msgid "Remove"
-msgstr "Entfernen"
+#: src/z3c/form/browser/multi.py:68
+msgid "Remove selected"
+msgstr ""
#: src/z3c/form/browser/select.py:39
msgid "no value"
@@ -607,6 +607,9 @@
msgid "The schema of the field for which the template should be available"
msgstr "Das Feld, für welches das Template zur Verfügung stehen soll"
+#~ msgid "Remove"
+#~ msgstr "Entfernen"
+
#~ msgid "Data Provider"
#~ msgstr "Daten-Provider"
Modified: z3c.form/trunk/src/z3c/form/locales/fr/LC_MESSAGES/z3c.form.po
===================================================================
--- z3c.form/trunk/src/z3c/form/locales/fr/LC_MESSAGES/z3c.form.po 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/src/z3c/form/locales/fr/LC_MESSAGES/z3c.form.po 2009-02-04 01:13:03 UTC (rev 96053)
@@ -12,7 +12,7 @@
msgstr ""
"Project-Id-Version: z3c.form\n"
"Report-Msgid-Bugs-To: Zope 3 Developers <zope3-dev at zope.org>\n"
-"POT-Creation-Date: Tue Feb 3 23:21:02 2009\n"
+"POT-Creation-Date: Wed Feb 4 04:06:37 2009\n"
"PO-Revision-Date: 2008-09-05 16:20+0200\n"
"Last-Translator: Christophe Combelles <ccomb at free.fr>\n"
"Language-Team: Zope 3 French Users <zope3-french-user at lists.afpy.org>\n"
@@ -20,13 +20,13 @@
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: src/z3c/form/browser/multi.py:59 src/z3c/form/form.py:209
+#: src/z3c/form/browser/multi.py:63 src/z3c/form/form.py:209
msgid "Add"
msgstr "Ajouter"
-#: src/z3c/form/browser/multi.py:63
-msgid "Remove"
-msgstr "Supprimer"
+#: src/z3c/form/browser/multi.py:68
+msgid "Remove selected"
+msgstr ""
#: src/z3c/form/browser/select.py:39
msgid "no value"
@@ -599,6 +599,9 @@
msgid "The schema of the field for which the template should be available"
msgstr "Le champ pour lequel le gabarit doit être disponible"
+#~ msgid "Remove"
+#~ msgstr "Supprimer"
+
#~ msgid "Data Provider"
#~ msgstr "Fournisseur de données"
Modified: z3c.form/trunk/src/z3c/form/locales/ru/LC_MESSAGES/z3c.form.mo
===================================================================
(Binary files differ)
Modified: z3c.form/trunk/src/z3c/form/locales/ru/LC_MESSAGES/z3c.form.po
===================================================================
--- z3c.form/trunk/src/z3c/form/locales/ru/LC_MESSAGES/z3c.form.po 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/src/z3c/form/locales/ru/LC_MESSAGES/z3c.form.po 2009-02-04 01:13:03 UTC (rev 96053)
@@ -14,8 +14,8 @@
msgid ""
msgstr ""
"Project-Id-Version: Development/Unknown\n"
-"POT-Creation-Date: Tue Feb 3 22:47:11 2009\n"
-"PO-Revision-Date: 2009-02-03 23:22+0300\n"
+"POT-Creation-Date: Wed Feb 4 04:06:37 2009\n"
+"PO-Revision-Date: 2009-02-04 04:07+0300\n"
"Last-Translator: Dan Korostelev <nadako at gmail.com>\n"
"Language-Team: Zope 3 Developers <zope3-dev at zope.org>\n"
"MIME-Version: 1.0\n"
@@ -23,14 +23,14 @@
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: zope/app/locales/extract.py\n"
-#: src/z3c/form/browser/multi.py:59
+#: src/z3c/form/browser/multi.py:63
#: src/z3c/form/form.py:209
msgid "Add"
msgstr "ÐобавиÑÑ"
-#: src/z3c/form/browser/multi.py:63
-msgid "Remove"
-msgstr "УдалиÑÑ"
+#: src/z3c/form/browser/multi.py:68
+msgid "Remove selected"
+msgstr "УдалиÑÑ Ð²ÑбÑаннÑе"
#: src/z3c/form/browser/select.py:39
msgid "no value"
@@ -580,6 +580,8 @@
msgid "The schema of the field for which the template should be available"
msgstr "СÑ
ема полÑ, Ð´Ð»Ñ ÐºÐ¾ÑоÑого Ñаблон должен бÑÑÑ Ð´Ð¾ÑÑÑпен"
+#~ msgid "Remove"
+#~ msgstr "УдалиÑÑ"
#~ msgid "Data Provider"
#~ msgstr "ÐоÑÑавÑик даннÑÑ
"
#~ msgid "The component providing the data of the field for the widget."
Modified: z3c.form/trunk/src/z3c/form/locales/z3c.form.pot
===================================================================
--- z3c.form/trunk/src/z3c/form/locales/z3c.form.pot 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/src/z3c/form/locales/z3c.form.pot 2009-02-04 01:13:03 UTC (rev 96053)
@@ -14,7 +14,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Development/Unknown\n"
-"POT-Creation-Date: Tue Feb 3 23:21:02 2009\n"
+"POT-Creation-Date: Wed Feb 4 04:06:37 2009\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
"Language-Team: Zope 3 Developers <zope3-dev at zope.org>\n"
@@ -23,13 +23,13 @@
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: zope/app/locales/extract.py\n"
-#: src/z3c/form/browser/multi.py:59
+#: src/z3c/form/browser/multi.py:63
#: src/z3c/form/form.py:209
msgid "Add"
msgstr ""
-#: src/z3c/form/browser/multi.py:63
-msgid "Remove"
+#: src/z3c/form/browser/multi.py:68
+msgid "Remove selected"
msgstr ""
#: src/z3c/form/browser/select.py:39
Modified: z3c.form/trunk/src/z3c/form/locales/zh_CN/LC_MESSAGES/z3c.form.po
===================================================================
--- z3c.form/trunk/src/z3c/form/locales/zh_CN/LC_MESSAGES/z3c.form.po 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/src/z3c/form/locales/zh_CN/LC_MESSAGES/z3c.form.po 2009-02-04 01:13:03 UTC (rev 96053)
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
-"POT-Creation-Date: Tue Feb 3 23:21:02 2009\n"
+"POT-Creation-Date: Wed Feb 4 04:06:37 2009\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -11,13 +11,13 @@
"X-Poedit-Language: Chinese\n"
"X-Poedit-Country: CHINA\n"
-#: src/z3c/form/browser/multi.py:59 src/z3c/form/form.py:209
+#: src/z3c/form/browser/multi.py:63 src/z3c/form/form.py:209
msgid "Add"
msgstr "æ·»å "
-#: src/z3c/form/browser/multi.py:63
-msgid "Remove"
-msgstr "å é¤"
+#: src/z3c/form/browser/multi.py:68
+msgid "Remove selected"
+msgstr ""
#: src/z3c/form/browser/select.py:39
msgid "no value"
@@ -567,6 +567,9 @@
msgid "The schema of the field for which the template should be available"
msgstr "模æ¿å¯ç¨çå段"
+#~ msgid "Remove"
+#~ msgstr "å é¤"
+
#~ msgid "Data Provider"
#~ msgstr "æ°æ®æä¾è
"
Modified: z3c.form/trunk/src/z3c/form/tests/simple_groupedit.pt
===================================================================
--- z3c.form/trunk/src/z3c/form/tests/simple_groupedit.pt 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/src/z3c/form/tests/simple_groupedit.pt 2009-02-04 01:13:03 UTC (rev 96053)
@@ -14,18 +14,31 @@
</li>
</ul>
<form action=".">
+ <tal:XXX replace="nothing">
+ Here's an interesting bug with z3c.pt: If you move the
+ define-macro below into the <div class="row"/>, it will
+ render the widget repetition twice for some reason when
+ using the macro below in the group fieldsets. Also, it
+ randomly won't repeat twice in some cases when text nodes are
+ inserted between tags (I tried to add "a" right after the
+ last tag - <input type="text" tal:replace="blahblah" />
+ Good luck to z3c.pt debuggers. :-)
+
+ nadako
+ </tal:XXX>
+ <metal:block metal:define-macro="rows">
<div class="row"
- metal:define-macro="rows"
tal:repeat="widget view/widgets/values">
<b tal:condition="widget/error"
- tal:content="structure widget/error/render"
- /><label for=""
+ tal:content="structure widget/error/render" />
+ <label for=""
tal:attributes="for widget/id"
tal:content="widget/label" />
- <input type="text" tal:replace="structure widget/render"
- /></div>
+ <input type="text" tal:replace="structure widget/render" />
+ </div>
+ </metal:block>
<fieldset tal:condition="view/groups|nothing"
- tal:repeat="view view/groups">
+ tal:repeat="view view/groups">
<legend tal:condition="view/label"
tal:content="view/label">Label</legend>
<div metal:use-macro="template/macros/errors" />
Modified: z3c.form/trunk/src/z3c/form/tests/test_doc.py
===================================================================
--- z3c.form/trunk/src/z3c/form/tests/test_doc.py 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/src/z3c/form/tests/test_doc.py 2009-02-04 01:13:03 UTC (rev 96053)
@@ -141,7 +141,6 @@
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
checker=checker,
))
- #for setUp in (testing.setUpZPT, testing.setUpZ3CPT))
- for setUp in (testing.setUpZPT, ))
+ for setUp in (testing.setUpZPT, testing.setUpZ3CPT))
return unittest.TestSuite(itertools.chain(*tests))
Modified: z3c.form/trunk/src/z3c/form/widget.py
===================================================================
--- z3c.form/trunk/src/z3c/form/widget.py 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/src/z3c/form/widget.py 2009-02-04 01:13:03 UTC (rev 96053)
@@ -244,6 +244,7 @@
zope.interface.implements(interfaces.IMultiWidget)
allowAdding = True
+ allowRemoving = True
# you set showLabel to False or use another template for disable (sub)
# widget labels
showLabel = True
@@ -332,19 +333,33 @@
"""
oldLen = len(self.widgets)
self.widgets = []
+ idx = 0
if self.value:
- for idx, v in enumerate(self.value):
+ for v in self.value:
widget = self.getWidget(idx)
self.applyValue(widget, v)
self.widgets.append(widget)
+ idx += 1
missing = oldLen - len(self.widgets)
if missing > 0:
# add previous existing new added widgtes
- for i in range(missing):
- idx += 1
+ for i in xrange(missing):
widget = self.getWidget(idx)
self.widgets.append(widget)
+ idx += 1
+ def updateAllowAddRemove(self):
+ """Update the allowAdding/allowRemoving attributes
+ basing on field constraints and current number of widgets
+ """
+ if not zope.schema.interfaces.IMinMaxLen.providedBy(self.field):
+ return
+ max_length = self.field.max_length
+ min_length = self.field.min_length
+ num_items = len(self.widgets)
+ self.allowAdding = bool((not max_length) or (num_items < max_length))
+ self.allowRemoving = bool(num_items and (num_items > min_length))
+
@apply
def value():
"""This invokes updateWidgets on any value change e.g. update/extract."""
Modified: z3c.form/trunk/src/z3c/form/widget.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/widget.txt 2009-02-03 23:24:13 UTC (rev 96052)
+++ z3c.form/trunk/src/z3c/form/widget.txt 2009-02-04 01:13:03 UTC (rev 96053)
@@ -619,7 +619,61 @@
>>> multiWidget.value
[u'42', u'43']
+MultiWidget also declares the ``allowAdding`` and ``allowRemoving``
+attributes that can be used in browser presentation to control add/remove
+button availability. To ease working with common cases, the
+``updateAllowAddRemove`` method provided that will set those attributes
+in respect to field's min_length and max_length, if the field provides
+zope.schema.interfaces.IMinMaxLen interface.
+Let's define a field with min and max length constraints and create
+a widget for it.
+
+ >>> multiField = zope.schema.List(
+ ... value_type=zope.schema.Int(),
+ ... min_length=2,
+ ... max_length=5)
+
+ >>> request = TestRequest()
+ >>> multiWidget = widget.FieldWidget(multiField, widget.MultiWidget(request))
+
+Now, let's check if the function will do the right thing depending on
+the value:
+
+No value:
+
+ >>> multiWidget.updateAllowAddRemove()
+ >>> multiWidget.allowAdding, multiWidget.allowRemoving
+ (True, False)
+
+Minimum length:
+
+ >>> multiWidget.value = [u'3', u'5']
+ >>> multiWidget.updateAllowAddRemove()
+ >>> multiWidget.allowAdding, multiWidget.allowRemoving
+ (True, False)
+
+Some allowed length:
+
+ >>> multiWidget.value = [u'3', u'5', u'8', u'6']
+ >>> multiWidget.updateAllowAddRemove()
+ >>> multiWidget.allowAdding, multiWidget.allowRemoving
+ (True, True)
+
+Maximum length:
+
+ >>> multiWidget.value = [u'3', u'5', u'8', u'6', u'42']
+ >>> multiWidget.updateAllowAddRemove()
+ >>> multiWidget.allowAdding, multiWidget.allowRemoving
+ (False, True)
+
+Over maximum length:
+
+ >>> multiWidget.value = [u'3', u'5', u'8', u'6', u'42', u'45']
+ >>> multiWidget.updateAllowAddRemove()
+ >>> multiWidget.allowAdding, multiWidget.allowRemoving
+ (False, True)
+
Widget Events
-------------
More information about the Checkins
mailing list