[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