[Checkins] SVN: z3c.formjs/trunk/ - Made jsvalidator tests work.

Stephan Richter srichter at cosmos.phy.tufts.edu
Thu Jul 5 17:04:26 EDT 2007


Log message for revision 77485:
  - Made jsvalidator tests work.
  
  - Cleaned up code a bit.
  
  - Made entry in CHANGES.txt for the next release.
  
  

Changed:
  U   z3c.formjs/trunk/CHANGES.txt
  U   z3c.formjs/trunk/src/z3c/formjs/jsbutton.py
  U   z3c.formjs/trunk/src/z3c/formjs/jsevent.py
  U   z3c.formjs/trunk/src/z3c/formjs/jsvalidator.py
  U   z3c.formjs/trunk/src/z3c/formjs/jsvalidator.txt
  U   z3c.formjs/trunk/src/z3c/formjs/testing.py

-=-
Modified: z3c.formjs/trunk/CHANGES.txt
===================================================================
--- z3c.formjs/trunk/CHANGES.txt	2007-07-05 20:41:45 UTC (rev 77484)
+++ z3c.formjs/trunk/CHANGES.txt	2007-07-05 21:04:25 UTC (rev 77485)
@@ -2,9 +2,15 @@
 CHANGES
 =======
 
+Version 0.2.0 (??/??/2007)
+--------------------------
+
+- Feature: Implementation of AJAX-driven widget value validation.
+
+
 Version 0.1.0 (6/29/2007)
 -------------------------
 
 - Initial Release
 
-  * JS event association with fields and buttons.
+  * Feature: JS event association with fields and buttons.

Modified: z3c.formjs/trunk/src/z3c/formjs/jsbutton.py
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/jsbutton.py	2007-07-05 20:41:45 UTC (rev 77484)
+++ z3c.formjs/trunk/src/z3c/formjs/jsbutton.py	2007-07-05 21:04:25 UTC (rev 77485)
@@ -16,24 +16,20 @@
 $Id: $
 """
 __docformat__ = "reStructuredText"
-
 import sys
-
 import zope.schema
 import zope.interface
 import zope.location
 import zope.component
+from jquery.layer import IJQueryJavaScriptBrowserLayer
 from zope.app.pagetemplate import ViewPageTemplateFile
+from z3c.form import button, action, widget
+from z3c.form.interfaces import IButton, IButtonHandlers, IButtonForm
+from z3c.form.interfaces import IFieldWidget, IValue, IFormLayer
 
-from z3c.form import button, util, action, widget
-from z3c.form.interfaces import (IButton, IFieldWidget, IValue,
-                            IButtonHandlers, IFormLayer, IButtonForm)
+from z3c.formjs import interfaces, jsevent
 
-from jquery.layer import IJQueryJavaScriptBrowserLayer
 
-import interfaces, jsevent
-
-
 class ButtonWidget(widget.Widget):
     """A submit button of a form."""
     zope.interface.implementsOnly(interfaces.IButtonWidget)

Modified: z3c.formjs/trunk/src/z3c/formjs/jsevent.py
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/jsevent.py	2007-07-05 20:41:45 UTC (rev 77484)
+++ z3c.formjs/trunk/src/z3c/formjs/jsevent.py	2007-07-05 21:04:25 UTC (rev 77485)
@@ -16,19 +16,18 @@
 $Id: $
 """
 __docformat__ = "reStructuredText"
-
 import sys
-
+import zope.component
 from zope.interface import implements
-import zope.component
 from zope.publisher.interfaces.browser import IBrowserRequest
 from zope.traversing.interfaces import IPathAdapter, ITraversable
 from z3c.form import util, button
 from z3c.form.interfaces import IForm
 from jquery.layer import IJQueryJavaScriptBrowserLayer
 
-import interfaces
+from z3c.formjs import interfaces
 
+
 class JSEvent(object):
     """IJSEvent implementation.
 
@@ -87,10 +86,11 @@
     def render(self, widget, form):
         result = ''
         for eventName, handler in self.events.items():
-            event = zope.component.getUtility(interfaces.IJSEvent, name=eventName)
-            renderer = zope.component.queryMultiAdapter((event, self.request),
-                                                        interfaces.IJSEventRenderer,
-                                                        default=JQueryEventRenderer(event, self.request))
+            event = zope.component.getUtility(
+                interfaces.IJSEvent, name=eventName)
+            renderer = zope.component.queryMultiAdapter(
+                (event, self.request), interfaces.IJSEventRenderer,
+                default=JQueryEventRenderer(event, self.request))
             result += renderer.render(handler, widget.id, form) + '\n'
         return result
 
@@ -109,19 +109,32 @@
         #first render events attached to widgets
         for widget in filter(interfaces.IJSEventsWidget.providedBy,
                              self.form.widgets.values()):
-            renderer = zope.component.getMultiAdapter((widget.jsEvents, self.request),
-                                                     interfaces.IJSEventsRenderer)
+            renderer = zope.component.getMultiAdapter(
+                (widget.jsEvents, self.request), interfaces.IJSEventsRenderer)
             result += renderer.render(widget, self.form)
-        #render events attached to fields
+        # render events attached to fields
         if hasattr(self.form, 'jshandlers'):
             for field in self.form.fields.values():
                 handler = self.form.jshandlers.getHandler(field)
                 if handler is not None:
-                    renderer = zope.component.getMultiAdapter((handler.event, self.request),
-                                                              interfaces.IJSEventRenderer)
+                    renderer = zope.component.getMultiAdapter(
+                        (handler.event, self.request),
+                        interfaces.IJSEventRenderer)
                     # XXX: is this a safe way to get ids?
+                    # Answer: Yes it is, because field is a z3c.form Field!
                     id = self.form.widgets[field.__name__].id
                     result += renderer.render(handler, id, self.form) + '\n'
+            #render events attached to buttons
+            if hasattr(self.form, 'buttons'):
+                for key, button in self.form.buttons.items():
+                    handler = self.form.jshandlers.getHandler(button)
+                    if handler is not None:
+                        renderer = zope.component.getMultiAdapter((handler.event, self.request),
+                                                                  interfaces.IJSEventRenderer)
+                        # XXX: is this a safe way to get ids?
+                        id = self.form.actions[key].id
+                        result += renderer.render(handler, id, self.form) + '\n'
+
         return result
 
 
@@ -139,7 +152,8 @@
         self.event = event
 
     def render(self, handler, id, form):
-        return '$("#%s").bind("%s", function(){%s});' % (id, self.event.name, handler(form, id))
+        return '$("#%s").bind("%s", function(){%s});' % (
+                          id, self.event.name, handler(form, id))
 
 
 class Handlers(button.Handlers):
@@ -159,7 +173,8 @@
     def getHandler(self, button):
         """See z3c.form.interfaces.IButtonHandlers"""
         buttonProvided = zope.interface.providedBy(button)
-        return self._registry.lookup1(buttonProvided, interfaces.IJSEventHandler)
+        return self._registry.lookup1(
+            buttonProvided, interfaces.IJSEventHandler)
 
 
 class Handler(object):

Modified: z3c.formjs/trunk/src/z3c/formjs/jsvalidator.py
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/jsvalidator.py	2007-07-05 20:41:45 UTC (rev 77484)
+++ z3c.formjs/trunk/src/z3c/formjs/jsvalidator.py	2007-07-05 21:04:25 UTC (rev 77485)
@@ -18,20 +18,23 @@
 
 class JQueryBaseValidationRenderer(object):
 
-    def __init__(self, form, widgetID, request):
+    def __init__(self, form, field, request):
         self.form = form
-        self.widgetID = widgetID
+        self.field = field
         self.request = request
 
     def _ajaxURL(self):
+        widget = self.form.widgets[self.field.__name__]
         # build js expression for extracting widget value
         # XXX: Maybe we should adapt the widget to IJSValueExtractorRenderer?
-        valueString = '$("#%s").val()' % self.widgetID
+        valueString = '$("#%s").val()' % widget.id
 
         # build a js expression that joins valueString expression
-        queryString = '"?widget-id=%s&%s=" + %s' % (self.widgetID, self.widgetID.replace('-','.'), valueString)
+        queryString = '"?widget-id=%s&%s=" + %s' % (
+            widget.id, widget.name, valueString)
 
-        # build a js expression that joins form url, validate path, and query string
+        # build a js expression that joins form url, validate path, and query
+        # string
         ajaxURL = '"'+self.form.request.getURL() + '/validate" + ' + queryString
 
         # it should look something like this now:
@@ -70,7 +73,8 @@
 
     def render(self):
         jsrenderer = zope.component.queryMultiAdapter(
-            (self.form, self.field, self.form.request), interfaces.IJSMessageValidationRenderer)
+            (self.form, self.field, self.form.request),
+            interfaces.IJSMessageValidationRenderer)
         return jsrenderer.render()
 
 
@@ -81,6 +85,7 @@
     ValidationRenderer = None
 
     def _validate(self):
+        # XXX: Hard coded. Need a better approach.
         widgetID = self.request.get('widget-id')
         fieldName = widgetID.replace('form-widgets-','')
         self.fields = self.fields.select(fieldName)
@@ -90,7 +95,7 @@
     def publishTraverse(self, request, name):
         # 1. Look at all the traverser plugins, whether they have an answer.
         for traverser in zope.component.subscribers((self, request),
-                                     ITraverserPlugin):
+                                                    ITraverserPlugin):
             try:
                 return traverser.publishTraverse(request, name)
             except NotFound:

Modified: z3c.formjs/trunk/src/z3c/formjs/jsvalidator.txt
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/jsvalidator.txt	2007-07-05 20:41:45 UTC (rev 77484)
+++ z3c.formjs/trunk/src/z3c/formjs/jsvalidator.txt	2007-07-05 21:04:25 UTC (rev 77485)
@@ -16,6 +16,11 @@
     >>> from z3c.form.testing import setupFormDefaults
     >>> setupFormDefaults()
 
+    >>> import zope.component
+    >>> from z3c.form import error
+    >>> zope.component.provideAdapter(error.ValueErrorViewSnippet)
+
+
     >>> import zope.interface
     >>> import zope.schema
     >>> class IAddress(zope.interface.Interface):
@@ -37,27 +42,34 @@
 We will register a jquery renderer.
 
     >>> import zope.component
-    >>> zope.component.provideAdapter(jsvalidator.JQueryMessageValidationRenderer)
+    >>> zope.component.provideAdapter(
+    ...     jsvalidator.JQueryMessageValidationRenderer)
+
     >>> print edit.fieldValidator(edit, edit.fields['zip'])
-    $.get("http://127.0.0.1/validate" + "?widget-id=form-widgets-zip&value=" + $("#form-widgets-zip").val(),
-    function(data){
-    alert(data);
-    })
+    $.get("http://127.0.0.1/validate" +
+          "?widget-id=form-widgets-zip&form.widgets.zip=" +
+          $("#form-widgets-zip").val(),
+          function(data){
+              alert(data);
+          })
 
     >>> from zope.publisher.interfaces import IPublisherRequest
     >>> from z3c.traverser import traverser
-    >>> zope.component.provideSubscriptionAdapter(traverser.AttributeTraverserPlugin,
-    ...                                           (jsinterfaces.IAJAXValidator, IPublisherRequest))
+    >>> zope.component.provideSubscriptionAdapter(
+    ...     traverser.AttributeTraverserPlugin,
+    ...     (jsinterfaces.IAJAXValidator, IPublisherRequest))
+
     >>> from z3c.traverser.traverser import PluggableTraverser
-    >>> request = TestRequest(form={'widget-id':'form-widgets-zip',
-    ...                             'form.widgets.zip':'29132'})
+    >>> request = TestRequest(form={'widget-id' : 'form-widgets-zip',
+    ...                             'form.widgets.zip' : u'29132'})
     >>> edit = AddressEditForm(None, request)
     >>> edit.update()
     >>> PluggableTraverser(edit, request).publishTraverse(request, 'validate')()
     u''
+
     >>> request = TestRequest(form={'widget-id':'form-widgets-zip',
     ...                             'form.widgets.zip':'notazipcode'})
     >>> edit = AddressEditForm(None, request)
     >>> edit.update()
     >>> PluggableTraverser(edit, request).publishTraverse(request, 'validate')()
-    u''
\ No newline at end of file
+    u'The system could not process the given value.'

Modified: z3c.formjs/trunk/src/z3c/formjs/testing.py
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/testing.py	2007-07-05 20:41:45 UTC (rev 77484)
+++ z3c.formjs/trunk/src/z3c/formjs/testing.py	2007-07-05 21:04:25 UTC (rev 77485)
@@ -16,23 +16,19 @@
 $Id: $
 """
 __docformat__ = 'restructuredtext'
-
+import jquery.layer
 import os.path
-
+import z3c.form.interfaces
+import z3c.form.testing
 import zope.interface
 import zope.component
+from z3c.form.interfaces import IWidget, IFormLayer
 from zope.publisher.browser import TestRequest
 from zope.app.testing import setup
-import z3c.form.interfaces
-import z3c.form.testing
 
-import jquery.layer
 from z3c.formjs import jsbutton, jswidget, jsevent
-from z3c.formjs import interfaces
+from z3c.formjs import interfaces, browser
 
-from z3c.form.interfaces import IWidget, IFormLayer
-import browser
-
 class TestRequest(TestRequest):
     zope.interface.implements(jquery.layer.IJQueryJavaScriptBrowserLayer,
                               IFormLayer)
@@ -43,34 +39,31 @@
 
 def setUpEventUtilities():
     ## Event Utilities
-    zope.component.provideUtility(jsevent.CLICK, interfaces.IJSEvent, name='click')
-    zope.component.provideUtility(jsevent.DBLCLICK, interfaces.IJSEvent, name='dblclick')
-    zope.component.provideUtility(jsevent.LOAD, interfaces.IJSEvent, name='load')
-    zope.component.provideUtility(jsevent.CHANGE, interfaces.IJSEvent, name='change')
-    zope.component.provideUtility(jsevent.BLUR, interfaces.IJSEvent, name='blur')
-    zope.component.provideUtility(jsevent.FOCUS, interfaces.IJSEvent, name='focus')
-    zope.component.provideUtility(jsevent.KEYDOWN, interfaces.IJSEvent, name='keydown')
-    zope.component.provideUtility(jsevent.KEYUP, interfaces.IJSEvent, name='keyup')
-    zope.component.provideUtility(jsevent.MOUSEDOWN, interfaces.IJSEvent, name='mousedown')
-    zope.component.provideUtility(jsevent.MOUSEMOVE, interfaces.IJSEvent, name='mousemove')
-    zope.component.provideUtility(jsevent.MOUSEOUT, interfaces.IJSEvent, name='mouseout')
-    zope.component.provideUtility(jsevent.MOUSEOVER, interfaces.IJSEvent, name='mouseover')
-    zope.component.provideUtility(jsevent.MOUSEUP, interfaces.IJSEvent, name='mouseup')
-    zope.component.provideUtility(jsevent.RESIZE, interfaces.IJSEvent, name='resize')
-    zope.component.provideUtility(jsevent.SELECT, interfaces.IJSEvent, name='select')
-    zope.component.provideUtility(jsevent.SUBMIT, interfaces.IJSEvent, name='submit')
+    zope.component.provideUtility(jsevent.CLICK, name='click')
+    zope.component.provideUtility(jsevent.DBLCLICK, name='dblclick')
+    zope.component.provideUtility(jsevent.LOAD, name='load')
+    zope.component.provideUtility(jsevent.CHANGE, name='change')
+    zope.component.provideUtility(jsevent.BLUR, name='blur')
+    zope.component.provideUtility(jsevent.FOCUS, name='focus')
+    zope.component.provideUtility(jsevent.KEYDOWN, name='keydown')
+    zope.component.provideUtility(jsevent.KEYUP, name='keyup')
+    zope.component.provideUtility(jsevent.MOUSEDOWN, name='mousedown')
+    zope.component.provideUtility(jsevent.MOUSEMOVE, name='mousemove')
+    zope.component.provideUtility(jsevent.MOUSEOUT, name='mouseout')
+    zope.component.provideUtility(jsevent.MOUSEOVER, name='mouseover')
+    zope.component.provideUtility(jsevent.MOUSEUP, name='mouseup')
+    zope.component.provideUtility(jsevent.RESIZE, name='resize')
+    zope.component.provideUtility(jsevent.SELECT, name='select')
+    zope.component.provideUtility(jsevent.SUBMIT, name='submit')
 
 
 def setUp(test):
     test.globs = {'root': setup.placefulSetUp(True)}
     z3c.form.testing.setupFormDefaults()
-    zope.component.provideAdapter(jsbutton.JSButtonAction,
-                                  (jquery.layer.IJQueryJavaScriptBrowserLayer,
-                                   interfaces.IJSButton),
-                                  z3c.form.interfaces.IFieldWidget)
-    zope.component.provideAdapter(jswidget.JSEventsWidget,
-                                  (interfaces.IJSEvents, IWidget),
-                                  interfaces.IJSEventsWidget)
+    zope.component.provideAdapter(
+        jsbutton.JSButtonAction, provides=z3c.form.interfaces.IFieldWidget)
+    zope.component.provideAdapter(
+        jswidget.JSEventsWidget, provides=interfaces.IJSEventsWidget)
     zope.component.provideAdapter(jsevent.JQueryEventRenderer)
 
     setUpEventUtilities()



More information about the Checkins mailing list