[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