[Checkins] SVN: z3c.formjs/trunk/ add capability for ajax handlers to return dictionaries lists and tuples that get automatically converted into JSON strings.

Paul Carduner paulcarduner at gmail.com
Sun May 11 19:58:21 EDT 2008


Log message for revision 86662:
  add capability for ajax handlers to return dictionaries lists and tuples that get automatically converted into JSON strings.

Changed:
  U   z3c.formjs/trunk/CHANGES.txt
  U   z3c.formjs/trunk/setup.py
  U   z3c.formjs/trunk/src/z3c/formjs/ajax.py
  U   z3c.formjs/trunk/src/z3c/formjs/ajax.txt

-=-
Modified: z3c.formjs/trunk/CHANGES.txt
===================================================================
--- z3c.formjs/trunk/CHANGES.txt	2008-05-11 23:34:56 UTC (rev 86661)
+++ z3c.formjs/trunk/CHANGES.txt	2008-05-11 23:58:21 UTC (rev 86662)
@@ -5,7 +5,9 @@
 Version 0.3.1 (unreleased)
 --------------------------
 
-- ...
+- Feature: When AJAX handlers return complex data structures (dictionaries,
+  lists and tuples), the data is automatically converted into JSON
+  format before delivery.
 
 Version 0.3.0 (2007-10-03)
 -------------------------

Modified: z3c.formjs/trunk/setup.py
===================================================================
--- z3c.formjs/trunk/setup.py	2008-05-11 23:34:56 UTC (rev 86661)
+++ z3c.formjs/trunk/setup.py	2008-05-11 23:58:21 UTC (rev 86662)
@@ -81,6 +81,7 @@
         'zope.publisher',
         'zope.schema',
         'zope.traversing',
+        'simplejson',
         ],
     dependency_links = ['http://download.zope.org/distribution'],
     zip_safe = False,

Modified: z3c.formjs/trunk/src/z3c/formjs/ajax.py
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/ajax.py	2008-05-11 23:34:56 UTC (rev 86661)
+++ z3c.formjs/trunk/src/z3c/formjs/ajax.py	2008-05-11 23:58:21 UTC (rev 86662)
@@ -17,6 +17,7 @@
 """
 __docformat__ = "reStructuredText"
 import sys
+import simplejson
 import zope.component
 import zope.interface
 from zope.publisher.interfaces import NotFound
@@ -46,7 +47,13 @@
         self.func = func
 
     def __call__(self, view):
-        return self.func(view)
+        result = self.func(view)
+        if type(result) in (dict, list, set):
+            try:
+                result = simplejson.dumps(result)
+            except TypeError:
+                result = str(result)
+        return result
 
     def __repr__(self):
         return "<%s %r>" % (self.__class__.__name__, self.func.__name__)

Modified: z3c.formjs/trunk/src/z3c/formjs/ajax.txt
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/ajax.txt	2008-05-11 23:34:56 UTC (rev 86661)
+++ z3c.formjs/trunk/src/z3c/formjs/ajax.txt	2008-05-11 23:58:21 UTC (rev 86662)
@@ -11,21 +11,23 @@
 AJAX Request Handlers
 ---------------------
 
-AJAX requests are sent from a client-side JavaScript script to the web server.
-The request may contain form data or any other request data and the server
-sends back a response based on the request.  The functionality for handling
-requests and returning responses is already handled by browser views.  But
-browser views can be a bit overkill for handling very simple requests and
-responses that don't necessarily involve rendering full page templates.  The
-``ajax`` module allows you to quickly build short ajax request handlers into
-your form.
+AJAX requests are sent from a client-side JavaScript script to the web
+server.  The request may contain form data or any other request data.
+The server then sends back a response based on the request.  The
+functionality for handling requests and returning responses is already
+handled by browser views.  But browser views can be a bit overkill for
+handling very simple requests and responses that don't necessarily
+involve rendering full page templates.  The ``ajax`` module allows you
+to quickly build short ajax request handlers into your form.
 
 We will first do the necessary setup steps:
 
   >>> from z3c.form.testing import setupFormDefaults
   >>> setupFormDefaults()
 
-Now we will create a simple form with an AJAX request handler.
+Now we will create a simple form with two AJAX request handlers, one
+that returns a simple string, and another that returns a complex
+python object.
 
   >>> from z3c.form import form
   >>> from z3c.formjs import interfaces
@@ -36,6 +38,13 @@
   ...     def pingBack(self):
   ...         message = self.request.get('message', 'Nothing to ping back.')
   ...         return "from %r: %s" % (self, message)
+  ...
+  ...     @ajax.handler
+  ...     def info(self):
+  ...         return {'class':self.__class__.__name__,
+  ...                 'requestKeys':self.request.keys(),
+  ...                 'requestVals':self.request.values(),
+  ...                 'size':len(self.request.keys())}
 
 The ``AJAXRequestHandler`` class provides the ``IAJAXRequestHandler``
 interface.  This means that the ``PingForm`` class will have an
@@ -47,7 +56,7 @@
   >>> request = TestRequest()
   >>> ping = PingForm(None, request)
   >>> ping.ajaxRequestHandlers
-  <AJAXHandlers ['pingBack']>
+  <AJAXHandlers ['pingBack', 'info']>
   >>> ping.pingBack
   <AJAXHandler 'pingBack'>
   >>> ping.ajaxRequestHandlers['pingBack']
@@ -61,15 +70,32 @@
   >>> print ping.pingBack(ping)
   from <PingForm ...>: Nothing to ping back.
 
-Before the handler is called we put an ``AJAXView`` class around it:
+As you can see, we get the simple string returned.  When an AJAX
+handler returns a complex data structure, it is converted into a
+JSON string.
 
+  >>> print ping.info(ping)
+  {"requestKeys": ["CONTENT_LENGTH", "HTTP_HOST",
+                   "SERVER_URL", "GATEWAY_INTERFACE"],
+   "requestVals": ["0", "127.0.0.1",
+                   "http://127.0.0.1", "TestFooInterface/1.0"],
+   "class": "PingForm",
+   "size": 4}
+
+Before the handler is called we put an ``AJAXView`` class around it,
+which takes the handler, request, and form as parameters:
+
   >>> pingView = ajax.AJAXView(ping.pingBack, ping.request, ping)
 
-The ping AJAX view can simply be called:
+The ping AJAX view can simply be called like a normal view:
 
   >>> print pingView()
   from <PingForm ...>: Nothing to ping back.
 
+
+Exposing an AJAX handler via a URL
+----------------------------------
+
 To hook up the AJAX handler as a public URL, we use a pluggable traverser
 traversal plugin. Let's first instantiate a pluggable traverser providing our
 form as the context.



More information about the Checkins mailing list