[Checkins] SVN: z3c.formjs/trunk/src/z3c/formjs/j z3c.formjs is now
100% test-covered again.
Stephan Richter
srichter at cosmos.phy.tufts.edu
Thu Aug 23 15:52:49 EDT 2007
Log message for revision 79172:
z3c.formjs is now 100% test-covered again.
Changed:
U z3c.formjs/trunk/src/z3c/formjs/jqueryrenderer.txt
U z3c.formjs/trunk/src/z3c/formjs/jsclientevent.py
U z3c.formjs/trunk/src/z3c/formjs/jsclientevent.txt
U z3c.formjs/trunk/src/z3c/formjs/jsfunction.txt
-=-
Modified: z3c.formjs/trunk/src/z3c/formjs/jqueryrenderer.txt
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/jqueryrenderer.txt 2007-08-23 19:35:04 UTC (rev 79171)
+++ z3c.formjs/trunk/src/z3c/formjs/jqueryrenderer.txt 2007-08-23 19:52:48 UTC (rev 79172)
@@ -134,3 +134,80 @@
"?widget-name=zip&form.zip=" + $("#form-zip").val(),
function(msg){applyErrorMessage("form-zip", msg)}
)
+
+
+``IWidgetSwitcher`` Renderer
+----------------------------
+
+This renderer defines how JavaScript switches the widget between display and
+input mode. This particular implementation actually leaves all the work up to
+a JavaScript function called ``switchWidget('widget-id', html)`` passing in
+the widget id of the widget to switch and the HTML with which the old content
+is replaced with.
+
+So let's create a widget switcher instance:
+
+ >>> from zope.app.folder import rootFolder
+ >>> root = rootFolder()
+ >>> form = Form(root, request)
+ >>> form.__name__ = 'form.html'
+
+ >>> widget = Widget(request)
+ >>> widget.id = 'form-zip'
+ >>> widget.name = 'form.zip'
+ >>> widget.__name__ = 'zip'
+
+ >>> from z3c.formjs import jsswitch
+ >>> switcher = jsswitch.WidgetSwitcher(form, widget, 'display')
+
+Let's now register the renderer:
+
+ >>> zope.component.provideAdapter(
+ ... jqueryrenderer.JQueryWidgetSwitcherRenderer)
+
+Now we can render the script:
+
+ >>> renderer = zope.component.getMultiAdapter(
+ ... (switcher, request), interfaces.IRenderer)
+ >>> renderer.update()
+ >>> print renderer.render()
+ $.get("http://127.0.0.1/form.html/@@ajax/getDisplayWidget?widget-name=zip",
+ function(html){switchWidget("form-zip", html)}
+ )
+
+``IWidgetSaver`` Renderer
+-------------------------
+
+This renderer defines how JavaScript saves the value of a widget. The widget
+submits the data to the form and waits for the response. The response and the
+widget id are then forwarded to a JavaScript function
+``saveWidget('widget-id', 'message')``. It is up the user to implement that
+function for their Web site.
+
+So let's create a widget saver instance:
+
+ >>> root = rootFolder()
+ >>> form = Form(root, request)
+ >>> form.__name__ = 'form.html'
+
+ >>> widget = Widget(request)
+ >>> widget.id = 'form-zip'
+ >>> widget.name = 'form.zip'
+ >>> widget.__name__ = 'zip'
+
+ >>> saver = jsswitch.WidgetSaver(form, widget)
+
+Let's now register the renderer:
+
+ >>> zope.component.provideAdapter(
+ ... jqueryrenderer.JQueryWidgetSaverRenderer)
+
+Now we can render the script:
+
+ >>> renderer = zope.component.getMultiAdapter(
+ ... (saver, request), interfaces.IRenderer)
+ >>> renderer.update()
+ >>> print renderer.render()
+ $.get("http://127.0.0.1/form.html/@@ajax/saveWidgetValue?widget-name=zip&form.zip=" + $("#form-zip").val(),
+ function(msg){saveWidget("form-zip", msg)}
+ )
Modified: z3c.formjs/trunk/src/z3c/formjs/jsclientevent.py
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/jsclientevent.py 2007-08-23 19:35:04 UTC (rev 79171)
+++ z3c.formjs/trunk/src/z3c/formjs/jsclientevent.py 2007-08-23 19:52:48 UTC (rev 79172)
@@ -51,7 +51,7 @@
def copy(self):
"""See interfaces.IClientEventHandlers"""
- handlers = Handlers()
+ handlers = ClientEventHandlers()
for eventSpec, handler in self._handlers:
handlers.addHandler(eventSpec, handler)
return handlers
Modified: z3c.formjs/trunk/src/z3c/formjs/jsclientevent.txt
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/jsclientevent.txt 2007-08-23 19:35:04 UTC (rev 79171)
+++ z3c.formjs/trunk/src/z3c/formjs/jsclientevent.txt 2007-08-23 19:52:48 UTC (rev 79172)
@@ -2,31 +2,30 @@
Mapping Events Between Server and Client
========================================
-The ``jsclientevent`` module of this package provides an extremely
-minimal event framework whereby events that occur on the server, such
-as ``IObjectModifiedEvent``s, propagate to a clients browser through
-injected JavaScript function calls. This is not to be confused with
-"action events" that occur on the client such as onClick.
+The ``jsclientevent`` module of this package provides an extremely minimal
+event framework whereby events that occur on the server, such as
+``IObjectModifiedEvent`` events, propagate to a client's browser through
+injected JavaScript function calls. This is not to be confused with "action
+events" that occur on the client such as "onClick".
>>> from z3c.formjs import jsclientevent
-There are several components these types of interactions. First there
-are the server events, which, for example, are thrown on a state
-change. Next there is a client listener, which is just a javascript
-function that gets called when the event occurs, and finally there is
-the "event transport" which allows the server to call a function
-defined on the client side.
+There are several components to these types of interactions. First there are
+the *server events*, which, for example, are thrown on a state change. Next
+there is a *client listener*, which is just a javascript function that gets
+called when the event occurs, and finally there is the *event transport* which
+allows the server to call a function defined on the client side.
Client Side Handler
--------------------
-The client side event handler is just a snippet of JavaScript that
-gets executed when the event occurs. The server injects this
-javascript onto the page via an ajax response.
+The client side event handler is just a snippet of JavaScript that gets
+executed when the event occurs. The server injects this javascript onto the
+page via an ajax response.
Let's create a simple view class with an event listener for the
-IObjectModifiedEvent
+``IObjectModifiedEvent`` event:
>>> from zope.lifecycleevent.interfaces import IObjectModifiedEvent
>>> class View(object):
@@ -35,10 +34,9 @@
... def modifiedListener(self, event):
... return 'alert("object modified: %s");' % event.object
-The argument passed to the ``listener`` decorator is a list (or tuple)
-of the required interfaces for the event handler. This is just like
-the set of interfaces one would pass to the
-zope.component.provideHandler function.
+The argument passed to the ``listener`` decorator is a list (or tuple) of the
+required interfaces for the event handler. This is just like the set of
+interfaces one would pass to the ``zope.component.provideHandler()`` function.
The decorator also registers this client side event handler with a local
component registry that is accessed through the ``jsClientListeners``
@@ -48,16 +46,40 @@
<ClientEventHandlers
[<ClientEventHandler for (<InterfaceClass ...IObjectModifiedEvent>,)>]>
+Client Event Handlers instances can be copied,
+
+ >>> copy = View.jsClientListeners.copy()
+ >>> copy
+ <ClientEventHandlers
+ [<ClientEventHandler for (<InterfaceClass ...IObjectModifiedEvent>,)>]>
+
+ >>> copy is View.jsClientListeners
+ False
+
+and also be added amongst each other:
+
+ >>> View.jsClientListeners + copy
+ <ClientEventHandlers
+ [<ClientEventHandler for (<InterfaceClass ...IObjectModifiedEvent>,)>,
+ <ClientEventHandler for (<InterfaceClass ...IObjectModifiedEvent>,)>]>
+
+Other objects cannot be added to those handlers instances:
+
+ >>> View.jsClientListeners + 1
+ Traceback (most recent call last):
+ ...
+ NotImplementedError
+
+
Server Side Listeners
---------------------
-So, we need a subscriber on the server side that listens for
-server side events that are relevant and sticks the event into the
-request to be rendered by the form at the end of the interaction.
-First we need to register the subscriber.
+We also need a subscriber on the server side that listens for relevant server
+side events and sticks the event into the request so it can be processed by
+the form at the end of the interaction. First we need to register the
+subscriber.
>>> import zope.component
- >>> from zope.component.interfaces import IObjectEvent
>>> zope.component.provideHandler(jsclientevent.serverToClientEventLoader)
>>> from zope.event import notify
@@ -73,7 +95,7 @@
>>> from z3c.formjs import testing
>>> testing.setupRenderers()
-Create a content component for an "article"
+Create a content component for an "article":
>>> import zope.interface
>>> import zope.schema
@@ -147,4 +169,5 @@
dom from the ``eventInjections`` attribute.
>>> print form.eventInjections
- alert("This event occured: <zope.app.event.objectevent.ObjectModifiedEvent object at ...>");
+ alert("This event occured:
+ <zope.app.event.objectevent.ObjectModifiedEvent object at ...>");
Modified: z3c.formjs/trunk/src/z3c/formjs/jsfunction.txt
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/jsfunction.txt 2007-08-23 19:35:04 UTC (rev 79171)
+++ z3c.formjs/trunk/src/z3c/formjs/jsfunction.txt 2007-08-23 19:52:48 UTC (rev 79172)
@@ -102,17 +102,20 @@
>>> class View(object):
...
- ... @jsfunction.function()
+ ... @jsfunction.function('ns')
... def show(self, title):
... return u"alert('Title' + title);"
>>> print View.jsFunctions.render()
- function show(title) {
- alert('Title' + title);
+ var ns = {
+ show: function(title) {
+ alert('Title' + title);
+ }
}
And that is realy everything that there is to it.
+
Calling JSFunctions from Python
-------------------------------
@@ -121,17 +124,28 @@
the call method the arguments to be rendered.
>>> View.show.call(u"Some Title")
- "show('Some Title');"
+ "ns.show('Some Title');"
>>> View.show.call("Some Title")
- "show('Some Title');"
+ "ns.show('Some Title');"
>>> View.show.call(3.0)
- 'show(3.0);'
+ 'ns.show(3.0);'
>>> View.show.call(1)
- 'show(1);'
+ 'ns.show(1);'
>>> View.show.call(True)
- 'show(true);'
+ 'ns.show(true);'
Unsupported data types are just rendered as stritree/ngs.
>>> View.show.call(object())
- "show('<object object at ...>');"
+ "ns.show('<object object at ...>');"
+
+Functions without namespaces also render correctly:
+
+ >>> class View(object):
+ ...
+ ... @jsfunction.function()
+ ... def show(self, title):
+ ... return u"alert('Title' + title);"
+
+ >>> View.show.call(u"Some Title")
+ "show('Some Title');"
More information about the Checkins
mailing list