[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