[Checkins] SVN: z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/ get basic rendering of jquery style client side event notification

Paul Carduner paulcarduner at gmail.com
Thu Jul 10 13:00:38 EDT 2008


Log message for revision 88195:
  get basic rendering of jquery style client side event notification

Changed:
  U   z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/interfaces.py
  U   z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jqueryrenderer.py
  U   z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsclientevent.py
  U   z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsclientevent.txt
  U   z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/testing.py

-=-
Modified: z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/interfaces.py
===================================================================
--- z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/interfaces.py	2008-07-10 16:14:02 UTC (rev 88194)
+++ z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/interfaces.py	2008-07-10 17:00:36 UTC (rev 88195)
@@ -401,12 +401,15 @@
         """Execute the handler."""
 
 
-class IAutoEventHandler(IClientEventHandler):
-    """Marker interface to auto event handler can be rendered."""
+class INotifyClientHandler(IClientEventHandler):
+    """An event handler which catches server side events and
+    translates them into client side event notifications."""
 
     event = zope.schema.Field(
-        title=u"The event that took place.")
+        title=u"Event",
+        description=u"The event that took place.")
 
+
 class IClientEvent(zope.interface.Interface):
     """A representation of an event for a client side framework.
 

Modified: z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jqueryrenderer.py
===================================================================
--- z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jqueryrenderer.py	2008-07-10 16:14:02 UTC (rev 88194)
+++ z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jqueryrenderer.py	2008-07-10 17:00:36 UTC (rev 88195)
@@ -101,10 +101,10 @@
             '\n  '.join([r.render() for r in self.renderers]) )
 
 
-class JQueryAutoEventHandlerRenderer(object):
+class JQueryNotifyClientHandlerRenderer(object):
+    zope.component.adapts(interfaces.INotifyClientHandler,
+                          IJQueryJavaScriptBrowserLayer)
     zope.interface.implements(interfaces.IRenderer)
-    zope.component.adapts(interfaces.IAutoEventHandler,
-                          IJQueryJavaScriptBrowserLayer)
 
     def __init__(self, handler, request):
         self.handler = handler

Modified: z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsclientevent.py
===================================================================
--- z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsclientevent.py	2008-07-10 16:14:02 UTC (rev 88194)
+++ z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsclientevent.py	2008-07-10 17:00:36 UTC (rev 88195)
@@ -98,21 +98,24 @@
     return createListener
 
 
-class AutoEventHandler(object):
+class NotifyClientHandler(object):
     """An implementation of a client event handler that automatically
     produces javascript that is meant to call client side event notifiers."""
-    zope.interface.implements(interfaces.IAutoEventHandler)
+    zope.interface.implements(interfaces.INotifyClientHandler)
 
-    event = None
+    event = None # we only know the event once the handler is called.
 
     def __call__(self, form, event):
+        self.event = event
         renderer = zope.component.getMultiAdapter(
             (self, form.request), interfaces.IRenderer)
         renderer.update()
-        self.event = event
         return renderer.render()
 
+    def __repr__(self):
+        return '<%s>' % (self.__class__.__name__)
 
+
 @zope.component.adapter(zope.component.interfaces.IObjectEvent)
 def serverToClientEventLoader(event):
     """Event handler that listens for server side events

Modified: z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsclientevent.txt
===================================================================
--- z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsclientevent.txt	2008-07-10 16:14:02 UTC (rev 88194)
+++ z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsclientevent.txt	2008-07-10 17:00:36 UTC (rev 88195)
@@ -106,7 +106,8 @@
 interfaces representing the object type and the event type) and the
 handler function itself.
 
-  >>> def someHandler(event): return str(event)
+  >>> def someHandler(event):
+  ...     return str(event)
   >>> from zope.component.interfaces import IObjectEvent
   >>> View.jsClientListeners.addHandler((Interface, IObjectEvent), someHandler)
   >>> View.jsClientListeners.getHandlers(objectEvent2)
@@ -155,7 +156,7 @@
 The thing that separates server handlers from client handlers is that
 the former is called immediately on notification, while the latter is
 "rendered" towards the end of an interaction (request/response
-cycle) - posisbly long after the original event notification occurs.
+cycle) - possibly long after the original event notification occurs.
 So we need a special server side handler whose job it is to catch all
 the events that occur during an interaction and store them in memory
 so that they are available at render time.
@@ -172,7 +173,7 @@
 handlers.  We cannot store the event in the form itself since the
 event handler has no knowledge of what context the original
 notification occurred, or which form the event is meant for.  Instead
-we must store the event in the request object, which we can be
+we must store the event in the request object, which can be
 magically obtained from the current interaction.  The current
 interaction has multiple "participations," which represent different
 types of requests.  The handler provided above finds the request that
@@ -258,8 +259,8 @@
   >>> request = TestRequest(form={'form.widgets.title':u'New Title',
   ...                             'form.buttons.apply':u'Apply'})
 
-  >>> form = ArticleEditForm(article, request)
-  >>> form.update()
+  >>> editform = ArticleEditForm(article, request)
+  >>> editform.update()
 
 Note that the form framework throws an IObjectModifedEvent when it
 applies changes.  Since we have performed this action without having
@@ -276,8 +277,8 @@
   ...                             'form.buttons.apply':u'Apply'})
   >>> management.newInteraction(request)
 
-  >>> form = ArticleEditForm(article, request)
-  >>> form.update()
+  >>> editform = ArticleEditForm(article, request)
+  >>> editform.update()
 
   >>> request.annotations[jsclientevent.CLIENT_EVENT_REQUEST_KEY]
   [<zope.app.event.objectevent.ObjectModifiedEvent object at ...>]
@@ -286,7 +287,7 @@
 ``eventCalls`` property.  This property returns a list of all events
 for which there are registered listeners/renderers.
 
-  >>> form.eventCalls
+  >>> editform.eventCalls
   [<zope.app.event.objectevent.ObjectModifiedEvent object at ...>]
 
 If there are no handlers for the thrown event, they do not appear in
@@ -299,17 +300,64 @@
   [<zope.app.event.objectevent.ObjectModifiedEvent object at ...>,
    <zope.app.event.objectevent.ObjectEvent object at ...>]
 
-  >>> form.eventCalls
+  >>> editform.eventCalls
   [<zope.app.event.objectevent.ObjectModifiedEvent object at ...>]
 
 We can then call all the listeners/renderers for the events with
 handlers and get back the renderer javascript injection using the
 ``eventInjections`` property:
 
-  >>> print form.eventInjections
+  >>> print editform.eventInjections
   alert("This event occured:
          <zope.app.event.objectevent.ObjectModifiedEvent object at ...>");
 
 Note that it is up to the page that sent the (possibly) asynchronous
 http request to the form to properly handle the javascript injection
 in the response, i.e. by inserting it into the dom using <script> tags.
+
+Lets not forget to end the interaction we created.
+
+  >>> management.endInteraction()
+
+
+NotifyClient Handler
+--------------------
+
+There is an additional ``IClientEventHandler`` implementation which
+can be used with client side event frameworks.  This type of handler
+effectively reproduces server side event notifications on the
+client.  By creating notifications on the client for server side
+events, view components can interact with each other directly on the
+client.
+
+For example, we may have several viewlets being rendered on a
+page along with a form that can modify objects in the database using
+an asychronus HTTP request.  When the form modifies the object, any
+viewlets containing information about the object must be updated as
+well.  In order to avoid a full page reload, the rendered
+viewlets can update themselves by listening for these events.
+
+Let's create another view that sends event notifications to the client.
+
+  >>> class ArticleEditForm(jsclientevent.ClientEventsForm,
+  ...                       form.EditForm):
+  ...     fields = field.Fields(IArticle)
+  ...     jsClientListeners = jsclientevent.ClientEventHandlers()
+  ...     jsClientListeners.addHandler((Interface, IObjectModifiedEvent,),
+  ...                                  jsclientevent.NotifyClientHandler())
+
+Now we will instantiate the form and modify the object.
+
+  >>> request = TestRequest(form={'form.widgets.title':u'New Title Two',
+  ...                             'form.buttons.apply':u'Apply'})
+
+  >>> management.newInteraction(request)
+  >>> editform = ArticleEditForm(article, request)
+  >>> editform.update()
+
+  >>> print editform.eventInjections
+  $().trigger("ObjectModifiedEvent")
+
+Lets not forget to end the interaction we created.
+
+  >>> management.endInteraction()

Modified: z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/testing.py
===================================================================
--- z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/testing.py	2008-07-10 16:14:02 UTC (rev 88194)
+++ z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/testing.py	2008-07-10 17:00:36 UTC (rev 88195)
@@ -162,6 +162,28 @@
         return "$.get('saveValue', function(msg){%s}\n)" % saveCall
 
 
+class NotifyClientHandlerRenderer(object):
+    zope.component.adapts(interfaces.INotifyClientHandler,
+                          IBrowserRequest)
+    zope.interface.implements(interfaces.IRenderer)
+
+    def __init__(self, handler, request):
+        self.handler = handler
+        self.request = request
+
+    def update(self):
+        pass
+
+    def render(self):
+        try:
+            event = interfaces.IClientEvent(self.handler.event,
+                                            self.request)
+            event = event.render()
+        except:
+            event = '"%s"' % self.handler.event.__class__.__name__
+        return '$().trigger(%s)' % event
+
+
 def setupRenderers():
     zope.component.provideAdapter(IdSelectorRenderer)
     zope.component.provideAdapter(CSSSelectorRenderer)
@@ -171,6 +193,7 @@
     zope.component.provideAdapter(WidgetSwitcherRenderer)
     zope.component.provideAdapter(LabelWidgetSwitcherRenderer)
     zope.component.provideAdapter(WidgetSaverRenderer)
+    zope.component.provideAdapter(NotifyClientHandlerRenderer)
 
 
 def addTemplate(form, filename):



More information about the Checkins mailing list