[Checkins] SVN: z3c.form/trunk/ - Feature: Implemented
``ImageButton``, ``ImageAction``,
Stephan Richter
srichter at cosmos.phy.tufts.edu
Wed Oct 3 12:55:30 EDT 2007
Log message for revision 80556:
- Feature: Implemented ``ImageButton``, ``ImageAction``,
``ImageWidget``, and ``ImageFieldWidget`` to support imge submit
buttons.
Changed:
U z3c.form/trunk/CHANGES.txt
U z3c.form/trunk/src/z3c/form/browser/README.txt
U z3c.form/trunk/src/z3c/form/browser/configure.zcml
A z3c.form/trunk/src/z3c/form/browser/image.py
A z3c.form/trunk/src/z3c/form/browser/image.txt
A z3c.form/trunk/src/z3c/form/browser/image.zcml
A z3c.form/trunk/src/z3c/form/browser/image_display.pt
A z3c.form/trunk/src/z3c/form/browser/image_input.pt
U z3c.form/trunk/src/z3c/form/browser/interfaces.py
U z3c.form/trunk/src/z3c/form/browser/tests.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/interfaces.py
-=-
Modified: z3c.form/trunk/CHANGES.txt
===================================================================
--- z3c.form/trunk/CHANGES.txt 2007-10-03 16:39:13 UTC (rev 80555)
+++ z3c.form/trunk/CHANGES.txt 2007-10-03 16:55:30 UTC (rev 80556)
@@ -5,11 +5,8 @@
Version 1.7.0 (9/??/2007)
-------------------------
-- Bug: When an error occurred during processing of the request the
- widget ended up been security proxies and the system started
- throwing `TraversalError's trying to access the `label' attribute of
- the widget. Declared that the widgets require the `zope.Public'
- permission in order to access these attributes.
+- Feature: Implemented ``ImageButton``, ``ImageAction``, ``ImageWidget``, and
+ ``ImageFieldWidget`` to support imge submit buttons.
- Feature: The ``AttributeField`` data manager now supports adapting
the content to the fields interface when the content doesn't implement
@@ -19,6 +16,15 @@
fields. They are not available by default but can be set using the
``widgetFactory`` attribute.
+- Bug: More lingual issues have been fixed in the documentation. Thanks to
+ Martijn Faassen for doing this.
+
+- Bug: When an error occurred during processing of the request the
+ widget ended up been security proxies and the system started
+ throwing `TraversalError's trying to access the `label' attribute of
+ the widget. Declared that the widgets require the `zope.Public'
+ permission in order to access these attributes.
+
- Bug: When rendering a widget the ``style`` attribute was not honored. Thanks
to Andreas Reuleaux for reporting.
Modified: z3c.form/trunk/src/z3c/form/browser/README.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/README.txt 2007-10-03 16:39:13 UTC (rev 80555)
+++ z3c.form/trunk/src/z3c/form/browser/README.txt 2007-10-03 16:55:30 UTC (rev 80556)
@@ -195,7 +195,6 @@
disabled="disabled" />
-
Bytes
-----
@@ -251,6 +250,7 @@
<span class="selected-option">Yes</span>
</span>
+
Date
----
@@ -388,6 +388,55 @@
</span>
+ImageButton
+-----------
+
+Let's say we have a simple image field that uses the ``pressme.png`` image.
+
+ >>> from z3c.form import button
+ >>> field = button.ImageButton(
+ ... image=u'pressme.png',
+ ... title=u'Press me!')
+
+When the widget is created, the system converts the relative image path to an
+absolute image path by looking up the resource. For this to work, we have to
+setup some of the traversing machinery:
+
+ # Traversing setup
+ >>> from zope.traversing import testing
+ >>> testing.setUp()
+
+ # Resource namespace
+ >>> import zope.component
+ >>> from zope.traversing.interfaces import ITraversable
+ >>> from zope.traversing.namespace import resource
+ >>> zope.component.provideAdapter(
+ ... resource, (None,), ITraversable, name="resource")
+ >>> zope.component.provideAdapter(
+ ... resource, (None, None), ITraversable, name="resource")
+
+ # Register the "pressme.png" resource
+ >>> from zope.app.publisher.browser.resource import Resource
+ >>> testing.browserResource('pressme.png', Resource)
+
+Now we are ready to instantiate the widget:
+
+ >>> widget = setupWidget(field)
+ >>> widget.update()
+ >>> print widget.render()
+ <input type="image" id="foo" name="bar"
+ class="image-widget imagebutton-field"
+ src="http://127.0.0.1/@@/pressme.png"
+ value="Press me!" />
+
+ >>> widget.mode = interfaces.DISPLAY_MODE
+ >>> print widget.render()
+ <input type="image" id="foo" name="bar"
+ class="image-widget imagebutton-field"
+ src="http://127.0.0.1/@@/pressme.png"
+ value="Press me!" disabled="disabled" />
+
+
Int
---
Modified: z3c.form/trunk/src/z3c/form/browser/configure.zcml
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/configure.zcml 2007-10-03 16:39:13 UTC (rev 80555)
+++ z3c.form/trunk/src/z3c/form/browser/configure.zcml 2007-10-03 16:55:30 UTC (rev 80556)
@@ -6,6 +6,7 @@
<include file="button.zcml" />
<include file="checkbox.zcml" />
<include file="file.zcml" />
+ <include file="image.zcml" />
<include file="orderedselect.zcml" />
<include file="password.zcml" />
<include file="radio.zcml" />
Added: z3c.form/trunk/src/z3c/form/browser/image.py
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/image.py (rev 0)
+++ z3c.form/trunk/src/z3c/form/browser/image.py 2007-10-03 16:55:30 UTC (rev 80556)
@@ -0,0 +1,56 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Submit Widget Implementation
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.component
+import zope.interface
+import zope.traversing.api
+from zope.schema.fieldproperty import FieldProperty
+from zope.app.component import hooks
+
+from z3c.form import interfaces
+from z3c.form.widget import FieldWidget
+from z3c.form.browser import button
+from z3c.form.browser.interfaces import IHTMLImageWidget
+
+
+class ImageWidget(button.ButtonWidget):
+ """A image button of a form."""
+ zope.interface.implementsOnly(interfaces.IImageWidget)
+ src = FieldProperty(IHTMLImageWidget['src'])
+ klass = u'image-widget'
+
+ def extract(self, default=interfaces.NOVALUE):
+ """See z3c.form.interfaces.IWidget."""
+ if self.name + '.x' not in self.request:
+ return default
+ return {
+ 'x': int(self.request[self.name + '.x']),
+ 'y': int(self.request[self.name + '.y']),
+ 'value': self.request[self.name]}
+
+
+ at zope.component.adapter(interfaces.IImageButton, interfaces.IFormLayer)
+ at zope.interface.implementer(interfaces.IFieldWidget)
+def ImageFieldWidget(field, request):
+ image = FieldWidget(field, ImageWidget(request))
+ image.value = field.title
+ # Get the full resource URL for the image:
+ site = hooks.getSite()
+ image.src = zope.traversing.api.traverse(
+ site, '++resource++' + field.image, request=request)()
+ return image
Property changes on: z3c.form/trunk/src/z3c/form/browser/image.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3c.form/trunk/src/z3c/form/browser/image.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/image.txt (rev 0)
+++ z3c.form/trunk/src/z3c/form/browser/image.txt 2007-10-03 16:55:30 UTC (rev 80556)
@@ -0,0 +1,74 @@
+=============
+Image Widget
+=============
+
+The image widget allows you to submit a form to the server by clicking on an
+image. The "image" type of the "INPUT" element is described here:
+
+http://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#edef-INPUT
+
+As for all widgets, the image widget must provide the new ``IWidget``
+interface:
+
+ >>> from zope.interface.verify import verifyClass
+ >>> from z3c.form import interfaces
+ >>> from z3c.form.browser import image
+
+ >>> verifyClass(interfaces.IWidget, image.ImageWidget)
+ True
+
+The widget can be instantiated only using the request:
+
+ >>> from z3c.form.testing import TestRequest
+ >>> request = TestRequest()
+
+ >>> widget = image.ImageWidget(request)
+
+Before rendering the widget, one has to set the name and id of the widget:
+
+ >>> widget.id = 'widget.id'
+ >>> widget.name = 'widget.name'
+
+We also need to register the template for the widget:
+
+ >>> import zope.component
+ >>> from zope.pagetemplate.interfaces import IPageTemplate
+ >>> from z3c.form.testing import getPath
+ >>> from z3c.form.widget import WidgetTemplateFactory
+
+ >>> zope.component.provideAdapter(
+ ... WidgetTemplateFactory(getPath('image_input.pt'), 'text/html'),
+ ... (None, None, None, None, interfaces.IImageWidget),
+ ... IPageTemplate, name=interfaces.INPUT_MODE)
+
+If we render the widget we get a simple input element:
+
+ >>> print widget.render()
+ <input type="image" id="widget.id" name="widget.name"
+ class="image-widget" />
+
+Setting an image source for the widget effectively changes the "src" attribute:
+
+ >>> widget.src = u'widget.png'
+ >>> print widget.render()
+ <input type="image" id="widget.id" name="widget.name"
+ class="image-widget" src="widget.png" />
+
+
+Let's now make sure that we can extract user entered data from a widget:
+
+ >>> widget.request = TestRequest(
+ ... form={'widget.name.x': '10',
+ ... 'widget.name.y': '20',
+ ... 'widget.name': 'value'})
+ >>> widget.update()
+ >>> sorted(widget.extract().items())
+ [('value', 'value'), ('x', 10), ('y', 20)]
+
+
+If nothing is found in the request, the default is returned:
+
+ >>> widget.request = TestRequest()
+ >>> widget.update()
+ >>> widget.extract()
+ <NOVALUE>
Property changes on: z3c.form/trunk/src/z3c/form/browser/image.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.form/trunk/src/z3c/form/browser/image.zcml
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/image.zcml (rev 0)
+++ z3c.form/trunk/src/z3c/form/browser/image.zcml 2007-10-03 16:55:30 UTC (rev 80556)
@@ -0,0 +1,24 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:z3c="http://namespaces.zope.org/z3c"
+ i18n_domain="z3c.form">
+
+ <adapter
+ factory=".image.ImageFieldWidget"
+ />
+
+ <z3c:widgetTemplate
+ mode="display"
+ widget="z3c.form.interfaces.IImageWidget"
+ layer="z3c.form.interfaces.IFormLayer"
+ template="image_display.pt"
+ />
+
+ <z3c:widgetTemplate
+ mode="input"
+ widget="z3c.form.interfaces.IImageWidget"
+ layer="z3c.form.interfaces.IFormLayer"
+ template="image_input.pt"
+ />
+
+</configure>
Property changes on: z3c.form/trunk/src/z3c/form/browser/image.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.form/trunk/src/z3c/form/browser/image_display.pt
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/image_display.pt (rev 0)
+++ z3c.form/trunk/src/z3c/form/browser/image_display.pt 2007-10-03 16:55:30 UTC (rev 80556)
@@ -0,0 +1,6 @@
+<input type="image" id="" name="" class="" src="" value="" disabled="disabled"
+ tal:attributes="id view/id;
+ name view/name;
+ class view/klass;
+ src view/src;
+ value view/value" />
Property changes on: z3c.form/trunk/src/z3c/form/browser/image_display.pt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.form/trunk/src/z3c/form/browser/image_input.pt
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/image_input.pt (rev 0)
+++ z3c.form/trunk/src/z3c/form/browser/image_input.pt 2007-10-03 16:55:30 UTC (rev 80556)
@@ -0,0 +1,28 @@
+<input type="image" id="" name="" class="" src="" value=""
+ accesskey=""
+ tal:attributes="id view/id;
+ name view/name;
+ class view/klass;
+ style view/style;
+ lang view/lang;
+ onclick view/onclick;
+ ondblclick view/ondblclick;
+ onmousedown view/onmousedown;
+ onmouseup view/onmouseup;
+ onmouseover view/onmouseover;
+ onmousemove view/onmousemove;
+ onmouseout view/onmouseout;
+ onkeypress view/onkeypress;
+ onkeydown view/onkeydown;
+ onkeyup view/onkeyup;
+ src view/src;
+ value view/value;
+ disabled view/disabled;
+ tabindex view/tabindex;
+ onfocus view/onfocus;
+ onblur view/onblur;
+ onchange view/onchange;
+ readonly view/readonly;
+ alt view/alt;
+ accesskey view/accesskey;
+ onselect view/onselect" />
Property changes on: z3c.form/trunk/src/z3c/form/browser/image_input.pt
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: z3c.form/trunk/src/z3c/form/browser/interfaces.py
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/interfaces.py 2007-10-03 16:39:13 UTC (rev 80555)
+++ z3c.form/trunk/src/z3c/form/browser/interfaces.py 2007-10-03 16:55:30 UTC (rev 80556)
@@ -202,6 +202,15 @@
required=False)
+class IHTMLImageWidget(IHTMLInputWidget):
+ """A widget using the HTML INPUT element with type 'image'."""
+
+ src = zope.schema.TextLine(
+ title=u'Image Source',
+ description=(u'The source of the image used to display the widget.'),
+ required=True)
+
+
class IHTMLTextInputWidget(IHTMLFormElement):
"""A widget using the HTML INPUT element (for text types)."""
Modified: z3c.form/trunk/src/z3c/form/browser/tests.py
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/tests.py 2007-10-03 16:39:13 UTC (rev 80555)
+++ z3c.form/trunk/src/z3c/form/browser/tests.py 2007-10-03 16:55:30 UTC (rev 80556)
@@ -33,6 +33,10 @@
setUp=testing.setUp, tearDown=testing.tearDown,
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
),
+ DocFileSuite('image.txt',
+ setUp=testing.setUp, tearDown=testing.tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
DocFileSuite('orderedselect.txt',
setUp=testing.setUp, tearDown=testing.tearDown,
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
Modified: z3c.form/trunk/src/z3c/form/button.py
===================================================================
--- z3c.form/trunk/src/z3c/form/button.py 2007-10-03 16:39:13 UTC (rev 80555)
+++ z3c.form/trunk/src/z3c/form/button.py 2007-10-03 16:55:30 UTC (rev 80556)
@@ -21,11 +21,13 @@
import zope.interface
import zope.location
import zope.schema
+import zope.traversing.api
+from zope.app.component import hooks
from zope.interface import adapter
from zope.schema.fieldproperty import FieldProperty
from z3c.form import action, interfaces, util, value
-from z3c.form.browser import submit
+from z3c.form.browser import image, submit
from z3c.form.widget import AfterWidgetUpdateEvent
@@ -62,6 +64,22 @@
return '<%s %r %r>' %(
self.__class__.__name__, self.__name__, self.title)
+
+class ImageButton(Button):
+ """A simple image button in a form."""
+ zope.interface.implements(interfaces.IImageButton)
+
+ image = FieldProperty(interfaces.IImageButton['image'])
+
+ def __init__(self, image=None, *args, **kwargs):
+ self.image = image
+ super(ImageButton, self).__init__(*args, **kwargs)
+
+ def __repr__(self):
+ return '<%s %r %r>' %(
+ self.__class__.__name__, self.__name__, self.image)
+
+
class Buttons(util.SelectionManager):
"""Button manager."""
zope.interface.implements(interfaces.IButtons)
@@ -205,6 +223,25 @@
return self.name.replace('.', '-')
+class ImageButtonAction(image.ImageWidget, ButtonAction):
+ zope.component.adapts(interfaces.IFormLayer, interfaces.IImageButton)
+
+ def __init__(self, request, field):
+ action.Action.__init__(self, request, field.title)
+ submit.SubmitWidget.__init__(self, request)
+ self.field = field
+
+ @property
+ def src(self):
+ site = hooks.getSite()
+ src = zope.traversing.api.traverse(
+ site, '++resource++' + self.field.image, request=self.request)()
+ return src
+
+ def isExecuted(self):
+ return self.name + '.x' in self.request.form
+
+
class ButtonActions(action.Actions):
zope.component.adapts(
interfaces.IButtonForm,
Modified: z3c.form/trunk/src/z3c/form/button.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/button.txt 2007-10-03 16:39:13 UTC (rev 80555)
+++ z3c.form/trunk/src/z3c/form/button.txt 2007-10-03 16:55:30 UTC (rev 80556)
@@ -543,3 +543,43 @@
False
This is commonly needed when one wants to extend the handlers of a super-form.
+
+
+Image Buttons
+-------------
+
+A special type of button is the image button. Instead of creating a "submit"-
+or "button"-type input, an "image" button is created. An image button is a
+simple extension of a button, requiring an `image` argument to the constructor:
+
+ >>> imgSubmit = button.ImageButton(
+ ... name='submit',
+ ... title=u'Submit',
+ ... image=u'submit.png')
+ >>> imgSubmit
+ <ImageButton 'submit' u'submit.png'>
+
+Some browsers do not submit the value of the input, but only the coordinates
+of the image where the mouse click occurred. Thus we also need a special
+button action:
+
+ >>> from zope.publisher.browser import TestRequest
+ >>> request = TestRequest()
+
+ >>> imgSubmitAction = button.ImageButtonAction(request, imgSubmit)
+ >>> imgSubmitAction
+ <ImageButtonAction 'submit' u'Submit'>
+
+Initially, we did not click on the image:
+
+ >>> imgSubmitAction.isExecuted()
+ False
+
+Now the button is clicked:
+
+ >>> request = TestRequest(form={'submit.x': '3', 'submit.y': '4'})
+
+ >>> imgSubmitAction = button.ImageButtonAction(request, imgSubmit)
+ >>> imgSubmitAction.isExecuted()
+ True
+
Modified: z3c.form/trunk/src/z3c/form/configure.zcml
===================================================================
--- z3c.form/trunk/src/z3c/form/configure.zcml 2007-10-03 16:39:13 UTC (rev 80555)
+++ z3c.form/trunk/src/z3c/form/configure.zcml 2007-10-03 16:55:30 UTC (rev 80556)
@@ -87,6 +87,10 @@
provides=".interfaces.IButtonAction"
/>
<adapter
+ factory=".button.ImageButtonAction"
+ provides=".interfaces.IButtonAction"
+ />
+ <adapter
factory=".button.ButtonActions"
/>
<adapter
Modified: z3c.form/trunk/src/z3c/form/interfaces.py
===================================================================
--- z3c.form/trunk/src/z3c/form/interfaces.py 2007-10-03 16:39:13 UTC (rev 80555)
+++ z3c.form/trunk/src/z3c/form/interfaces.py 2007-10-03 16:55:30 UTC (rev 80556)
@@ -452,6 +452,9 @@
class ISubmitWidget(IWidget):
"""Submit widget."""
+class IImageWidget(IWidget):
+ """Submit widget."""
+
class IButtonWidget(IWidget):
"""Button widget."""
@@ -626,6 +629,15 @@
missing_value=None)
+class IImageButton(IButton):
+ """An image button in a form."""
+
+ image = zope.schema.TextLine(
+ title=_('Image Path'),
+ description=_('A relative image path to the root of the resources.'),
+ required=True)
+
+
class IButtons(ISelectionManager):
"""Button manager."""
More information about the Checkins
mailing list