Skip to content

Commit

Permalink
multiwidget: on item removal it left holes in the sequence of widgets
Browse files Browse the repository at this point in the history
objectwidget: did not apply values on widget.value=newvalue
  • Loading branch information
Adam Groszer committed Dec 15, 2008
1 parent c20b354 commit fb51401
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 35 deletions.
1 change: 1 addition & 0 deletions src/z3c/form/browser/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def handleAdd(self, action):
def handleRemove(self, action):
self.widgets = [widget for widget in self.widgets
if ('%s.remove' % (widget.name)) not in self.request]
self.value = [widget.value for widget in self.widgets]

@zope.interface.implementer(interfaces.IFieldWidget)
def multiFieldWidgetFactory(field, request):
Expand Down
68 changes: 62 additions & 6 deletions src/z3c/form/browser/multi.txt
Original file line number Diff line number Diff line change
Expand Up @@ -394,9 +394,9 @@ This is good so, because the Remove is an widget-internal submit action
</div>
</div>
</div>
<div id="widget-id-2-row" class="row">
<div id="widget-id-1-row" class="row">
<div class="label">
<label for="widget-id-2">
<label for="widget-id-1">
<span>Number</span>
<span class="required">*</span>
</label>
Expand All @@ -405,11 +405,11 @@ This is good so, because the Remove is an widget-internal submit action
<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" />
id="widget-id-1-remove"
name="widget.name.1.remove" />
</div>
<div class="multi-widget-input"><input
type="text" id="widget-id-2" name="widget.name.2"
type="text" id="widget-id-1" name="widget.name.1"
class="text-widget required int-field" value="44" />
</div>
</div>
Expand All @@ -425,7 +425,63 @@ This is good so, because the Remove is an widget-internal submit action
</div>
<input type="hidden" name="widget.name.count" value="2" />

Error handling is next. Let's use teh value "bad" (an invlaid integer literal)
Change again a value after delete:

>>> widget.request = TestRequest(form={'widget.name.count':u'2',
... 'widget.name.0':u'42',
... 'widget.name.1':u'45'})
>>> 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 id="widget-id-0-remove" name="widget.name.0.remove"
class="multi-widget-checkbox checkbox-widget"
type="checkbox" value="1" />
</div>
<div class="multi-widget-input">
<input id="widget-id-0" name="widget.name.0"
class="text-widget required int-field" value="42" type="text" />
</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 id="widget-id-1-remove" name="widget.name.1.remove"
class="multi-widget-checkbox checkbox-widget"
type="checkbox" value="1" />
</div>
<div class="multi-widget-input">
<input id="widget-id-1" name="widget.name.1"
class="text-widget required int-field" value="45" type="text" />
</div>
</div>
</div>
<div class="buttons">
<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" />
</div>
</div>
<input type="hidden" name="widget.name.count" value="2" />

Error handling is next. Let's use teh value "bad" (an invalid integer literal)
as input for our internal (sub) widget.

>>> from z3c.form.error import ErrorViewSnippet
Expand Down
72 changes: 48 additions & 24 deletions src/z3c/form/browser/objectmulti.txt
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,8 @@ Now let's store the new value:
</div>
<div class="widget">
<div class="multi-widget-checkbox">
<input class="multi-widget-checkbox checkbox-widget" id="foo-0-remove" name="foo.0.remove" type="checkbox" value="1">
<input class="multi-widget-checkbox checkbox-widget" id="foo-0-remove"
name="foo.0.remove" type="checkbox" value="1">
</div>
<div class="multi-widget-input">
<div class="object-widget required">
Expand All @@ -507,15 +508,18 @@ Now let's store the new value:
</label>
</div>
<div class="widget">
<input class="text-widget required int-field" id="foo-0-widgets-foofield" name="foo.0.widgets.foofield" type="text" value="42">
<input class="text-widget required int-field"
id="foo-0-widgets-foofield" name="foo.0.widgets.foofield"
type="text" value="42">
</div>
<div class="label">
<label for="foo-0-widgets-barfield">
<span>My dear bar</span>
</label>
</div>
<div class="widget">
<input class="text-widget int-field" id="foo-0-widgets-barfield" name="foo.0.widgets.barfield" type="text" value="666">
<input class="text-widget int-field" id="foo-0-widgets-barfield"
name="foo.0.widgets.barfield" type="text" value="666">
</div>
<input name="foo.0-empty-marker" type="hidden" value="1">
</div>
Expand All @@ -531,7 +535,8 @@ Now let's store the new value:
</div>
<div class="widget">
<div class="multi-widget-checkbox">
<input class="multi-widget-checkbox checkbox-widget" id="foo-1-remove" name="foo.1.remove" type="checkbox" value="1">
<input class="multi-widget-checkbox checkbox-widget" id="foo-1-remove"
name="foo.1.remove" type="checkbox" value="1">
</div>
<div class="multi-widget-input">
<div class="object-widget required">
Expand All @@ -542,15 +547,18 @@ Now let's store the new value:
</label>
</div>
<div class="widget">
<input class="text-widget required int-field" id="foo-1-widgets-foofield" name="foo.1.widgets.foofield" type="text" value="789">
<input class="text-widget required int-field"
id="foo-1-widgets-foofield" name="foo.1.widgets.foofield"
type="text" value="789">
</div>
<div class="label">
<label for="foo-1-widgets-barfield">
<span>My dear bar</span>
</label>
</div>
<div class="widget">
<input class="text-widget int-field" id="foo-1-widgets-barfield" name="foo.1.widgets.barfield" type="text" value="321">
<input class="text-widget int-field" id="foo-1-widgets-barfield"
name="foo.1.widgets.barfield" type="text" value="321">
</div>
<input name="foo.1-empty-marker" type="hidden" value="1">
</div>
Expand All @@ -566,7 +574,8 @@ Now let's store the new value:
</div>
<div class="widget">
<div class="multi-widget-checkbox">
<input class="multi-widget-checkbox checkbox-widget" id="foo-2-remove" name="foo.2.remove" type="checkbox" value="1">
<input class="multi-widget-checkbox checkbox-widget" id="foo-2-remove"
name="foo.2.remove" type="checkbox" value="1">
</div>
<div class="multi-widget-input">
<div class="object-widget required">
Expand All @@ -577,24 +586,29 @@ Now let's store the new value:
</label>
</div>
<div class="widget">
<input class="text-widget required int-field" id="foo-2-widgets-foofield" name="foo.2.widgets.foofield" type="text" value="46">
<input class="text-widget required int-field"
id="foo-2-widgets-foofield" name="foo.2.widgets.foofield"
type="text" value="46">
</div>
<div class="label">
<label for="foo-2-widgets-barfield">
<span>My dear bar</span>
</label>
</div>
<div class="widget">
<input class="text-widget int-field" id="foo-2-widgets-barfield" name="foo.2.widgets.barfield" type="text" value="98">
<input class="text-widget int-field" id="foo-2-widgets-barfield"
name="foo.2.widgets.barfield" type="text" value="98">
</div>
<input name="foo.2-empty-marker" type="hidden" value="1">
</div>
</div>
</div>
</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-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">
</div>
</div>
<input name="foo.count" type="hidden" value="3">
Expand Down Expand Up @@ -647,7 +661,8 @@ remove an existing value:
</div>
<div class="widget">
<div class="multi-widget-checkbox">
<input class="multi-widget-checkbox checkbox-widget" id="foo-0-remove" name="foo.0.remove" type="checkbox" value="1">
<input class="multi-widget-checkbox checkbox-widget" id="foo-0-remove"
name="foo.0.remove" type="checkbox" value="1">
</div>
<div class="multi-widget-input">
<div class="object-widget required">
Expand All @@ -658,59 +673,68 @@ remove an existing value:
</label>
</div>
<div class="widget">
<input class="text-widget required int-field" id="foo-0-widgets-foofield" name="foo.0.widgets.foofield" type="text" value="42">
<input class="text-widget required int-field"
id="foo-0-widgets-foofield" name="foo.0.widgets.foofield"
type="text" value="42">
</div>
<div class="label">
<label for="foo-0-widgets-barfield">
<span>My dear bar</span>
</label>
</div>
<div class="widget">
<input class="text-widget int-field" id="foo-0-widgets-barfield" name="foo.0.widgets.barfield" type="text" value="666">
<input class="text-widget int-field" id="foo-0-widgets-barfield"
name="foo.0.widgets.barfield" type="text" value="666">
</div>
<input name="foo.0-empty-marker" type="hidden" value="1">
</div>
</div>
</div>
</div>
<div class="row" id="foo-2-row">
<div class="row" id="foo-1-row">
<div class="label">
<label for="foo-2">
<label for="foo-1">
<span>my object widget</span>
<span class="required">*</span>
</label>
</div>
<div class="widget">
<div class="multi-widget-checkbox">
<input class="multi-widget-checkbox checkbox-widget" id="foo-2-remove" name="foo.2.remove" type="checkbox" value="1">
<input class="multi-widget-checkbox checkbox-widget" id="foo-1-remove"
name="foo.1.remove" type="checkbox" value="1">
</div>
<div class="multi-widget-input">
<div class="object-widget required">
<div class="label">
<label for="foo-2-widgets-foofield">
<label for="foo-1-widgets-foofield">
<span>My foo field</span>
<span class="required">*</span>
</label>
</div>
<div class="widget">
<input class="text-widget required int-field" id="foo-2-widgets-foofield" name="foo.2.widgets.foofield" type="text" value="46">
<input class="text-widget required int-field"
id="foo-1-widgets-foofield" name="foo.1.widgets.foofield"
type="text" value="46">
</div>
<div class="label">
<label for="foo-2-widgets-barfield">
<label for="foo-1-widgets-barfield">
<span>My dear bar</span>
</label>
</div>
<div class="widget">
<input class="text-widget int-field" id="foo-2-widgets-barfield" name="foo.2.widgets.barfield" type="text" value="98">
<input class="text-widget int-field" id="foo-1-widgets-barfield"
name="foo.1.widgets.barfield" type="text" value="98">
</div>
<input name="foo.2-empty-marker" type="hidden" value="1">
<input name="foo.1-empty-marker" type="hidden" value="1">
</div>
</div>
</div>
</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-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">
</div>
</div>
<input name="foo.count" type="hidden" value="2">
Expand Down
8 changes: 7 additions & 1 deletion src/z3c/form/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,14 @@ def get(self):
return value
def set(self, value):
self._value = value
# ensure that we apply our new values to the widgets
self.updateWidgets()

# ensure that we apply our new values to the widgets
if value is not interfaces.NOVALUE:
for name in zope.schema.getFieldNames(self.field.schema):
self.subform.widgets[name].value = value.get(name,
interfaces.NOVALUE)

return property(get, set)


Expand Down
9 changes: 5 additions & 4 deletions src/z3c/form/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,13 +265,10 @@ def counterMarker(self):

def getWidget(self, idx):
"""Setup widget based on index id with or without value."""
id = '%s-%i' % (self.id, idx)
name = '%s.%i' % (self.name, idx)
valueType = self.field.value_type
widget = zope.component.getMultiAdapter((valueType, self.request),
interfaces.IFieldWidget)
widget.name = name
widget.id = id
self.setName(widget, idx)
widget.mode = self.mode
#set widget.form (objectwidget needs this)
if interfaces.IFormAware.providedBy(self):
Expand All @@ -281,6 +278,10 @@ def getWidget(self, idx):
widget.update()
return widget

def setName(self, widget, idx):
widget.name = '%s.%i' % (self.name, idx)
widget.id = '%s-%i' % (self.id, idx)

def appendAddingWidget(self):
"""Simply append a new empty widget with correct (counter) name."""
# since we start with idx 0 (zero) we can use the len as next idx
Expand Down

0 comments on commit fb51401

Please sign in to comment.