[Checkins] SVN: z3c.form/trunk/ Fixed badness related to button
actions. The API is much cleaner now.
Stephan Richter
srichter at cosmos.phy.tufts.edu
Fri Jul 6 11:11:11 EDT 2007
Log message for revision 77519:
Fixed badness related to button actions. The API is much cleaner now.
Changed:
U z3c.form/trunk/CHANGES.txt
U z3c.form/trunk/src/z3c/form/adding.txt
U z3c.form/trunk/src/z3c/form/browser/button.py
U z3c.form/trunk/src/z3c/form/browser/submit.py
U z3c.form/trunk/src/z3c/form/button.py
U z3c.form/trunk/src/z3c/form/button.txt
U z3c.form/trunk/src/z3c/form/configure.zcml
U z3c.form/trunk/src/z3c/form/form.txt
U z3c.form/trunk/src/z3c/form/group.txt
U z3c.form/trunk/src/z3c/form/interfaces.py
U z3c.form/trunk/src/z3c/form/subform.txt
U z3c.form/trunk/src/z3c/form/testing.py
-=-
Modified: z3c.form/trunk/CHANGES.txt
===================================================================
--- z3c.form/trunk/CHANGES.txt 2007-07-06 14:58:10 UTC (rev 77518)
+++ z3c.form/trunk/CHANGES.txt 2007-07-06 15:11:10 UTC (rev 77519)
@@ -5,6 +5,11 @@
Version 1.5.0 (??/??/2007)
-------------------------
+- Feature: Restructured the approach to customize button actions, by requiring
+ the adapter to provide a new interface ``IButtonAction``. Also, an adapter
+ is now provided by default, still allowing cusotmization using the usual
+ methods though.
+
- Feature: Added button widget. While it is not very useful without
Javascript, it still belongs into this package for completion.
@@ -28,6 +33,8 @@
- Bug/Feature: Correctly create labels for radio button choices.
+- Bug: Button actions were never updated in the actions manager.
+
- Bug: Added tests for textarea widget.
Modified: z3c.form/trunk/src/z3c/form/adding.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/adding.txt 2007-07-06 14:58:10 UTC (rev 77518)
+++ z3c.form/trunk/src/z3c/form/adding.txt 2007-07-06 15:11:10 UTC (rev 77519)
@@ -85,7 +85,8 @@
</div>
<div class="action">
<input type="submit" id="form-buttons-add"
- name="form.buttons.add" class="submitWidget" value="Add" />
+ name="form.buttons.add" class="submitWidget button-field"
+ value="Add" />
</div>
</form>
</body>
Modified: z3c.form/trunk/src/z3c/form/browser/button.py
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/button.py 2007-07-06 14:58:10 UTC (rev 77518)
+++ z3c.form/trunk/src/z3c/form/browser/button.py 2007-07-06 15:11:10 UTC (rev 77519)
@@ -31,7 +31,8 @@
klass = u'buttonWidget'
def update(self):
- super(ButtonWidget, self).update()
+ # We do not need to use the widget's update method, because it is
+ # mostly about ectracting the value, which we do not need to do.
widget.addFieldClass(self)
Modified: z3c.form/trunk/src/z3c/form/browser/submit.py
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/submit.py 2007-07-06 14:58:10 UTC (rev 77518)
+++ z3c.form/trunk/src/z3c/form/browser/submit.py 2007-07-06 15:11:10 UTC (rev 77519)
@@ -19,22 +19,17 @@
import zope.component
import zope.interface
-from z3c.form import interfaces, widget
-from z3c.form.widget import Widget, FieldWidget
-from z3c.form.browser import widget
+from z3c.form import interfaces
+from z3c.form.widget import FieldWidget
+from z3c.form.browser import button
-class SubmitWidget(widget.HTMLInputWidget, Widget):
+class SubmitWidget(button.ButtonWidget):
"""A submit button of a form."""
zope.interface.implementsOnly(interfaces.ISubmitWidget)
-
klass = u'submitWidget'
- def update(self):
- super(SubmitWidget, self).update()
- widget.addFieldClass(self)
-
@zope.component.adapter(interfaces.IButton, interfaces.IFormLayer)
@zope.interface.implementer(interfaces.IFieldWidget)
def SubmitFieldWidget(field, request):
Modified: z3c.form/trunk/src/z3c/form/button.py
===================================================================
--- z3c.form/trunk/src/z3c/form/button.py 2007-07-06 14:58:10 UTC (rev 77518)
+++ z3c.form/trunk/src/z3c/form/button.py 2007-07-06 15:11:10 UTC (rev 77519)
@@ -185,10 +185,11 @@
class ButtonAction(action.Action, submit.SubmitWidget, zope.location.Location):
- zope.interface.implements(interfaces.IFieldWidget)
+ zope.interface.implements(interfaces.IButtonAction)
+ zope.component.adapts(interfaces.IFormLayer, interfaces.IButton)
- def __init__(self, request, field, name):
- action.Action.__init__(self, request, field.title, name)
+ def __init__(self, request, field):
+ action.Action.__init__(self, request, field.title)
submit.SubmitWidget.__init__(self, request)
self.field = field
@@ -213,33 +214,36 @@
def update(self):
"""See z3c.form.interfaces.IActions."""
- # Create a unique prefix
+ # Create a unique prefix.
prefix = util.expandPrefix(self.form.prefix)
prefix += util.expandPrefix(self.form.buttons.prefix)
+ # Walk through each field, making an action out of it.
for name, button in self.form.buttons.items():
- # Only create an action for the button, if the condition is
- # fulfilled
+ # Step 1: Only create an action for the button, if the condition is
+ # fulfilled.
if button.condition is not None and not button.condition(self.form):
continue
- fullName = prefix + name
- # Look up a button action factory
+ # Step 2: Get the action for the given button.
if button.actionFactory is not None:
buttonAction = button.actionFactory(self.request, button)
- buttonAction.name = fullName
else:
- buttonAction = zope.component.queryMultiAdapter(
- (self.request, button), interfaces.IFieldWidget)
- if buttonAction is not None:
- buttonAction.name = fullName
- # if one is not found, use the default
- else:
- buttonAction = ButtonAction(self.request, button, fullName)
- # Look up a potential custom title for the action.
+ buttonAction = zope.component.getMultiAdapter(
+ (self.request, button), interfaces.IButtonAction)
+ # Step 3: Set the name on the button
+ fullName = prefix + name
+ buttonAction.name = fullName
+ # Step 4: Set any custom attribute values.
title = zope.component.queryMultiAdapter(
(self.form, self.request, self.content, button, self),
interfaces.IValue, name='title')
if title is not None:
buttonAction.title = title.get()
+ # Step 5: Set the form
+ buttonAction.form = self.form
+ zope.interface.alsoProvides(buttonAction, interfaces.IFormAware)
+ # Step 6: Update the new action
+ buttonAction.update()
+ # Step 7: Add the widget to the manager
self._data_keys.append(name)
self._data_values.append(buttonAction)
self._data[name] = buttonAction
Modified: z3c.form/trunk/src/z3c/form/button.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/button.txt 2007-07-06 14:58:10 UTC (rev 77518)
+++ z3c.form/trunk/src/z3c/form/button.txt 2007-07-06 15:11:10 UTC (rev 77519)
@@ -48,8 +48,13 @@
>>> request = TestRequest()
>>> form = Form()
+We also have to register a button action factory for the buttons:
+
+ >>> zope.component.provideAdapter(
+ ... button.ButtonAction, provides=interfaces.IButtonAction)
+
Action managers are instantiated using the form, request, and
-context/content. A special button-action-manager implementation is avaialble
+context/content. A special button-action-manager implementation is available
in the ``button`` package:
>>> actions = button.ButtonActions(form, request, None)
@@ -65,21 +70,15 @@
It is possible to customize how a button is transformed into an action
by registering an adapter for the request and the button that provides
-IFieldWidget.
+``IButtonAction``.
>>> import zope.component
>>> from zope.publisher.interfaces.browser import IBrowserRequest
>>> class CustomButtonAction(button.ButtonAction):
... """Custom Button Action Class."""
- ... zope.interface.implements(interfaces.IFieldWidget)
- ... zope.component.adapts(IBrowserRequest, interfaces.IButton)
- ...
- ... def __init__(self, request, field):
- ... super(CustomButtonAction, self).__init__(request, field, None)
- >>> zope.component.provideAdapter(CustomButtonAction,
- ... (IBrowserRequest,interfaces.IButton),
- ... interfaces.IFieldWidget)
+ >>> zope.component.provideAdapter(
+ ... CustomButtonAction, provides=interfaces.IButtonAction)
Now if we rerun update we will get this other ButtonAction
implementation.
@@ -144,7 +143,7 @@
>>> print actions['apply'].render()
<input type="submit" id="form-buttons-apply"
- name="form.buttons.apply" class="submitWidget"
+ name="form.buttons.apply" class="submitWidget button-field"
value="Apply" />
So displaying is nice, but how do button handlers get executed? The action
Modified: z3c.form/trunk/src/z3c/form/configure.zcml
===================================================================
--- z3c.form/trunk/src/z3c/form/configure.zcml 2007-07-06 14:58:10 UTC (rev 77518)
+++ z3c.form/trunk/src/z3c/form/configure.zcml 2007-07-06 15:11:10 UTC (rev 77519)
@@ -78,8 +78,12 @@
factory=".term.BoolTerms"
/>
- <!-- Action Managers and Handlers -->
+ <!-- Actions, Action Managers and Handlers -->
<adapter
+ factory=".button.ButtonAction"
+ provides=".interfaces.IButtonAction"
+ />
+ <adapter
factory=".button.ButtonActions"
/>
<adapter
Modified: z3c.form/trunk/src/z3c/form/form.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/form.txt 2007-07-06 14:58:10 UTC (rev 77518)
+++ z3c.form/trunk/src/z3c/form/form.txt 2007-07-06 15:11:10 UTC (rev 77519)
@@ -321,7 +321,7 @@
</div>
<div class="action">
<input type="submit" id="form-buttons-add" name="form.buttons.add"
- class="submitWidget" value="Add" />
+ class="submitWidget button-field" value="Add" />
</div>
</form>
</body>
@@ -429,7 +429,7 @@
</div>
<div class="action">
<input type="submit" id="form-buttons-add" name="form.buttons.add"
- class="submitWidget" value="Add" />
+ class="submitWidget button-field" value="Add" />
</div>
</form>
</body>
@@ -617,11 +617,11 @@
...
<div class="action">
<input type="submit" id="form-buttons-add" name="form.buttons.add"
- class="submitWidget" value="Add" />
+ class="submitWidget button-field" value="Add" />
</div>
<div class="action">
<input type="submit" id="form-buttons-cancel" name="form.buttons.cancel"
- class="submitWidget" value="Cancel" />
+ class="submitWidget button-field" value="Cancel" />
</div>
...
@@ -717,7 +717,7 @@
</div>
<div class="action">
<input type="submit" id="form-buttons-apply" name="form.buttons.apply"
- class="submitWidget" value="Apply" />
+ class="submitWidget button-field" value="Apply" />
</div>
</form>
</body>
@@ -782,7 +782,7 @@
</div>
<div class="action">
<input type="submit" id="form-buttons-apply" name="form.buttons.apply"
- class="submitWidget" value="Apply" />
+ class="submitWidget button-field" value="Apply" />
</div>
</form>
</body>
@@ -932,7 +932,7 @@
</div>
<div class="action">
<input type="submit" id="form-buttons-apply"
- name="form.buttons.apply" class="submitWidget"
+ name="form.buttons.apply" class="submitWidget button-field"
value="Apply" />
</div>
</form>
Modified: z3c.form/trunk/src/z3c/form/group.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/group.txt 2007-07-06 14:58:10 UTC (rev 77518)
+++ z3c.form/trunk/src/z3c/form/group.txt 2007-07-06 15:11:10 UTC (rev 77519)
@@ -152,7 +152,7 @@
</fieldgroup>
<div class="action">
<input type="submit" id="form-buttons-add"
- name="form.buttons.add" class="submitWidget"
+ name="form.buttons.add" class="submitWidget button-field"
value="Add" />
</div>
</form>
@@ -341,7 +341,7 @@
</fieldgroup>
<div class="action">
<input type="submit" id="form-buttons-apply"
- name="form.buttons.apply" class="submitWidget"
+ name="form.buttons.apply" class="submitWidget button-field"
value="Apply" />
</div>
</form>
Modified: z3c.form/trunk/src/z3c/form/interfaces.py
===================================================================
--- z3c.form/trunk/src/z3c/form/interfaces.py 2007-07-06 14:58:10 UTC (rev 77518)
+++ z3c.form/trunk/src/z3c/form/interfaces.py 2007-07-06 15:11:10 UTC (rev 77519)
@@ -450,7 +450,6 @@
default=False,
required=False)
-
def update():
"""Setup widgets."""
@@ -459,6 +458,18 @@
"""
+class IFieldWidget(zope.interface.Interface):
+ """Offers a field attribute.
+
+ For advanced uses the widget will make decisions based on the field
+ it is rendered for.
+ """
+
+ field = zope.schema.Field(
+ title=_('Field'),
+ description=_('The schema field which the widget is representing.'),
+ required=True)
+
# ----[ Actions ]------------------------------------------------------------
class IAction(zope.interface.Interface):
@@ -518,6 +529,10 @@
"""Button manager."""
+class IButtonAction(IAction, IWidget, IFieldWidget):
+ """Button action."""
+
+
class IButtonHandlers(zope.interface.Interface):
"""A collection of handlers for buttons."""
@@ -588,19 +603,6 @@
form = zope.schema.Field()
-class IFieldWidget(zope.interface.Interface):
- """Offers a field attribute.
-
- For advanced uses the widget will make decisions based on the field
- it is rendered for.
- """
-
- field = zope.schema.Field(
- title=_('Field'),
- description=_('The schema field which the widget is representing.'),
- required=True)
-
-
class IForm(zope.interface.Interface):
"""Form"""
Modified: z3c.form/trunk/src/z3c/form/subform.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/subform.txt 2007-07-06 14:58:10 UTC (rev 77518)
+++ z3c.form/trunk/src/z3c/form/subform.txt 2007-07-06 15:11:10 UTC (rev 77519)
@@ -131,13 +131,13 @@
</div>
<div class="action">
<input type="submit" id="owner-buttons-apply"
- name="owner.buttons.apply" class="submitWidget"
+ name="owner.buttons.apply" class="submitWidget button-field"
value="Apply" />
</div>
</fieldset>
<div class="action">
<input type="submit" id="car-buttons-apply"
- name="car.buttons.apply" class="submitWidget"
+ name="car.buttons.apply" class="submitWidget button-field"
value="Apply" />
</div>
</form>
@@ -203,13 +203,13 @@
</div>
<div class="action">
<input type="submit" id="owner-buttons-apply"
- name="owner.buttons.apply" class="submitWidget"
+ name="owner.buttons.apply" class="submitWidget button-field"
value="Apply" />
</div>
</fieldset>
<div class="action">
<input type="submit" id="car-buttons-apply"
- name="car.buttons.apply" class="submitWidget"
+ name="car.buttons.apply" class="submitWidget button-field"
value="Apply" />
</div>
</form>
@@ -311,7 +311,7 @@
</fieldset>
<div class="action">
<input type="submit" id="car-buttons-apply"
- name="car.buttons.apply" class="submitWidget"
+ name="car.buttons.apply" class="submitWidget button-field"
value="Apply" />
</div>
</form>
@@ -407,7 +407,7 @@
</fieldset>
<div class="action">
<input type="submit" id="car-buttons-apply"
- name="car.buttons.apply" class="submitWidget"
+ name="car.buttons.apply" class="submitWidget button-field"
value="Apply" />
</div>
</form>
@@ -578,13 +578,13 @@
</div>
<div class="action">
<input type="submit" id="owner-buttons-apply"
- name="owner.buttons.apply" class="submitWidget"
+ name="owner.buttons.apply" class="submitWidget button-field"
value="Apply" />
</div>
</fieldset>
<div class="action">
<input type="submit" id="car-buttons-apply"
- name="car.buttons.apply" class="submitWidget"
+ name="car.buttons.apply" class="submitWidget button-field"
value="Apply" />
</div>
</form>
Modified: z3c.form/trunk/src/z3c/form/testing.py
===================================================================
--- z3c.form/trunk/src/z3c/form/testing.py 2007-07-06 14:58:10 UTC (rev 77518)
+++ z3c.form/trunk/src/z3c/form/testing.py 2007-07-06 15:11:10 UTC (rev 77519)
@@ -136,6 +136,9 @@
# Adapter for providing terms to radio list and other widgets
zope.component.provideAdapter(term.ChoiceTerms)
zope.component.provideAdapter(term.BoolTerms)
+ # Adapter to create an action from a button
+ zope.component.provideAdapter(
+ button.ButtonAction, provides=interfaces.IButtonAction)
# Adapter to use form.buttons to generate actions
zope.component.provideAdapter(button.ButtonActions)
# Adapter to use form.handlers to generate handle actions
More information about the Checkins
mailing list