[Checkins] SVN: Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/ first attempt at ajax based widget validation. still not functioning by javascript expressions are rendered correctly

Paul Carduner paulcarduner at gmail.com
Wed Jul 4 17:57:00 EDT 2007


Log message for revision 77437:
  first attempt at ajax based widget validation.  still not functioning by javascript expressions are rendered correctly

Changed:
  U   Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/interfaces.py
  A   Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/jsvalidator.py
  A   Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/jsvalidator.txt
  U   Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/tests.py

-=-
Modified: Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/interfaces.py
===================================================================
--- Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/interfaces.py	2007-07-04 21:15:33 UTC (rev 77436)
+++ Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/interfaces.py	2007-07-04 21:56:59 UTC (rev 77437)
@@ -124,3 +124,24 @@
 
     def update():
         """Setup actions."""
+
+
+class IAJAXValidator(Interface):
+    """A validator that sends back validation data sent from an ajax request."""
+
+    ValidationRenderer = schema.Object(
+                    schema=Interface,
+                    title=u"Validation Renderer")
+
+    def validate():
+        """return validation data."""
+
+
+class IJSMessageValidationRenderer(Interface):
+    """renders a js expression for sending/processing ajax validation requests."""
+
+    def __init__(form, field, request):
+        """store the form field and request, because this adapts those items."""
+
+    def render():
+        """Render the js expression."""

Added: Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/jsvalidator.py
===================================================================
--- Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/jsvalidator.py	                        (rev 0)
+++ Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/jsvalidator.py	2007-07-04 21:56:59 UTC (rev 77437)
@@ -0,0 +1,97 @@
+import zope.interface
+import zope.component
+from z3c.form.interfaces import IWidget, IField
+
+from jquery.layer import IJQueryJavaScriptBrowserLayer
+
+from z3c.formjs import interfaces
+
+
+## @zope.component.adapter(IWidget, IJQueryJavaScriptBrowserLayer)
+## @zope.interface.implementer(interfaces.IJSErrorMessageRenderer)
+## def JQueryErrorMessageRenderer(widgetID):
+##     return '''$.get()'''
+
+
+class JQueryBaseValidationRenderer(object):
+
+    def __init__(self, form, field, request):
+        self.form = form
+        self.field = field # z3c.form.field.Field instance!!!
+        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()' % (widget.id, )
+
+        # build a js expression that joins valueString expression
+        queryString = '"?widget-id=%s&value=" + %s' % (widget.id, valueString)
+
+        # 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:
+        # "path/to/form.html/validate" + "?widget-id=some-id&value=" + $("#some-id").val()
+        return ajaxURL
+
+
+class JQueryMessageValidationRenderer(JQueryBaseValidationRenderer):
+
+    zope.interface.implements(interfaces.IJSMessageValidationRenderer)
+    zope.component.adapts(interfaces.IAJAXValidator,
+                          IField,
+                          IJQueryJavaScriptBrowserLayer)
+
+    def render(self):
+        ajaxURL = self._ajaxURL()
+        # build a js expression that shows the user the error message
+        # XXX: later this should query for a renderer based on the widget
+        #     jsrenderer = zope.component.queryMultiAdapter(
+        #         (widget, self.request), interfaces.IJSErrorMessageRenderer)
+        #     messageSetter = jsrenderer.render()
+        messageSetter = 'alert(data);'
+        ajax = '$.get(%s,\nfunction(data){\n%s\n})' % (ajaxURL, messageSetter)
+        return ajax
+
+
+class MessageValidationRenderer(object):
+    """An intermediate class that performs adapter look ups.
+
+    This way you don't have to do as many adapter look ups in your Form class.
+    """
+
+    def __init__(self, form, field):
+        self.form = form
+        self.field = field
+
+    def render(self):
+        jsrenderer = zope.component.queryMultiAdapter(
+            (self.form, self.field, self.form.request), interfaces.IJSMessageValidationRenderer)
+        return jsrenderer.render()
+
+
+class BaseValidator(object):
+    zope.interface.implements(interfaces.IAJAXValidator)
+
+    ValidationRenderer = None
+
+    def _validate(self):
+        widgetID = self.request.get('widget-id')
+        self.fields = self.fields.select(widgetID)
+        self.updateWidgets()
+        return self.widgets.extract()
+
+
+class MessageValidator(BaseValidator):
+    '''Validator that sends error messages for widget in questiodn.'''
+    ValidationRenderer = MessageValidationRenderer
+
+    def validate(self):
+        data, errors = self._validate()
+        if errors:
+            return errors[0].doc()
+        return u'' # all OK
+


Property changes on: Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/jsvalidator.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/jsvalidator.txt
===================================================================
--- Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/jsvalidator.txt	                        (rev 0)
+++ Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/jsvalidator.txt	2007-07-04 21:56:59 UTC (rev 77437)
@@ -0,0 +1,42 @@
+==========================
+JavaScript Form Validation
+==========================
+
+Server-side validation via AJAX
+
+Message Validator
+-----------------
+
+This validator returns an error message for a given widget.
+
+    >>> from z3c.formjs import interfaces as jsinterfaces
+    >>> from z3c.formjs import jsvalidator, jsevent
+    >>> from z3c.form import form, field, interfaces
+
+    >>> import zope.interface
+    >>> import zope.schema
+    >>> class IAddress(zope.interface.Interface):
+    ...     zip = zope.schema.Int(title=u"Zip Code")
+
+
+    >>> class AddressEditForm(jsvalidator.MessageValidator, form.AddForm):
+    ...     fields = field.Fields(IAddress)
+    ...
+    ...     @jsevent.handler(interfaces.IField, event=jsevent.CHANGE)
+    ...     def fieldValidator(self, field):
+    ...         return self.ValidationRenderer(self, field).render()
+
+    >>> from z3c.formjs.testing import TestRequest
+    >>> request = TestRequest()
+    >>> edit = AddressEditForm(None, request)
+    >>> edit.update()
+
+We will register a jquery renderer.
+
+    >>> import zope.component
+    >>> 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);
+    })


Property changes on: Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/jsvalidator.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/tests.py
===================================================================
--- Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/tests.py	2007-07-04 21:15:33 UTC (rev 77436)
+++ Sandbox/pcardune/z3cFormJS/trunk/src/z3c/formjs/tests.py	2007-07-04 21:56:59 UTC (rev 77437)
@@ -16,6 +16,11 @@
             optionflags=zope.testing.doctest.NORMALIZE_WHITESPACE |
                         zope.testing.doctest.ELLIPSIS),
         zope.testing.doctest.DocFileSuite(
+            'jsvalidator.txt',
+            setUp=testing.setUp, tearDown=testing.tearDown,
+            optionflags=zope.testing.doctest.NORMALIZE_WHITESPACE |
+                        zope.testing.doctest.ELLIPSIS),
+        zope.testing.doctest.DocFileSuite(
             'jsbutton.txt',
             setUp=testing.setUp, tearDown=testing.tearDown,
             optionflags=zope.testing.doctest.NORMALIZE_WHITESPACE |



More information about the Checkins mailing list