[Checkins] SVN: z3c.formjs/trunk/src/z3c/formjs/jsclientevent. got events to be stored on the request object

Paul Carduner paulcarduner at gmail.com
Fri Aug 17 15:15:34 EDT 2007


Log message for revision 78911:
  got events to be stored on the request object

Changed:
  U   z3c.formjs/trunk/src/z3c/formjs/jsclientevent.py
  U   z3c.formjs/trunk/src/z3c/formjs/jsclientevent.txt

-=-
Modified: z3c.formjs/trunk/src/z3c/formjs/jsclientevent.py
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/jsclientevent.py	2007-08-17 16:53:31 UTC (rev 78910)
+++ z3c.formjs/trunk/src/z3c/formjs/jsclientevent.py	2007-08-17 19:15:34 UTC (rev 78911)
@@ -19,10 +19,54 @@
 import sys
 import zope.component
 import zope.interface
+from zope.security.management import getInteraction
+from zope.publisher.interfaces.browser import IBrowserRequest
 
 from z3c.formjs import interfaces, jsfunction
 
 def listener(eventType):
     """A decorator for defining a javascript function that is a listener."""
     namespace = "%s_%s" % (eventType.__module__.replace(".","_"), eventType.__name__)
-    return jsfunction.function(namespace)
+##     def createFunction(func):
+##         import pdb; pdb.set_trace()
+##         frame = sys._getframe(1)
+##         f_locals = frame.f_locals
+##         funcs = f_locals.setdefault('jsFunctions', jsfunction.JSFunctions())
+##         jsFunction = jsfunction.JSFunction(namespace, func)
+##         return funcs.add(jsFunction, namespace)
+
+    zope.component.provideHandler(serverToClientEventLoader, (eventType,))
+    return jsfunction.function(namespace) #createFunction
+
+CLIENT_EVENT_REQUEST_KEY = "z3c.formjs.jsclientevent.caughtEvents"
+
+def serverToClientEventLoader(event):
+    """Event handler that listens for server side events
+    and stores the event in the request to be picked up by
+    the form and rendered as a client side function call."""
+
+    #step 1: get the interaction
+    interaction = getInteraction()
+    participations = interaction.participations
+
+    #step 2: look for a request in the participation
+    request = None
+    for part in participations:
+        if IBrowserRequest.providedBy(part):
+            request = part
+            break
+    #if no request was found, we have nothing to do.
+    if request is None:
+        return
+    #step 3: add the event to the list of events this handler has caught.
+    events = request.annotations.setdefault(CLIENT_EVENT_REQUEST_KEY, [])
+    if event not in events:
+        events.append(event)
+
+
+class ClientEventsForm(object):
+    """Mixin class to support calling of client side events."""
+
+    @property
+    def eventCalls(self):
+        return self.request.annotations.get(CLIENT_EVENT_REQUEST_KEY, [])

Modified: z3c.formjs/trunk/src/z3c/formjs/jsclientevent.txt
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/jsclientevent.txt	2007-08-17 16:53:31 UTC (rev 78910)
+++ z3c.formjs/trunk/src/z3c/formjs/jsclientevent.txt	2007-08-17 19:15:34 UTC (rev 78911)
@@ -60,4 +60,79 @@
 
 
 Server Side Listeners
----------------------
\ No newline at end of file
+---------------------
+
+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.
+
+  >>> import zope.component
+  >>> zope.component.provideHandler(jsclientevent.serverToClientEventLoader,
+  ...                               (IObjectModifiedEvent,))
+
+  >>> from zope.event import notify
+  >>> from zope.lifecycleevent import ObjectModifiedEvent
+  >>> notify(ObjectModifiedEvent('foo'))
+
+Let's create a typical use case scenario:
+
+First the setup:
+
+  >>> from z3c.form.testing import setupFormDefaults
+  >>> setupFormDefaults()
+  >>> from z3c.formjs import testing
+  >>> testing.setupRenderers()
+
+
+Create a content component for an "article"
+
+  >>> import zope.interface
+  >>> import zope.schema
+  >>> class IArticle(zope.interface.Interface):
+  ...     title = zope.schema.TextLine(title=u'Title')
+
+  >>> class Article(object):
+  ...     zope.interface.implements(IArticle)
+  ...     title = u'Default Title'
+
+  >>> article = Article()
+  >>> article.title
+  u'Default Title'
+
+Create an Edit Form for said content component.
+
+  >>> from z3c.form import form, field
+  >>> class ArticleEditForm(jsclientevent.ClientEventsForm,
+  ...                       form.EditForm):
+  ...     fields = field.Fields(IArticle)
+  ...
+  ...     @jsclientevent.listener(IObjectModifiedEvent)
+  ...     def alertModifiedEvent(self, data):
+  ...         return ('alert("You modified the object.\ndata: "'
+  ...                 ' + data + "\nPlease reload the page."')
+
+Now we will instantiate the form and modify the object.
+
+  >>> from z3c.form.testing import TestRequest
+  >>> request = TestRequest(form={'form.widgets.title':u'New Title',
+  ...                             'form.buttons.apply':u'Apply'})
+  >>> from zope.security import management
+  >>> from zope.security.testing import Participation
+  >>> management.endInteraction()
+  >>> management.newInteraction(request)
+
+  >>> form = ArticleEditForm(article, request)
+  >>> form.update()
+
+The request tells the form to update the title of the article, and
+subsequently send out an object modified event.  This event gets
+picked up by our handler, and stored in the request's annotations
+
+  >>> request.annotations[jsclientevent.CLIENT_EVENT_REQUEST_KEY]
+  [<zope.app.event.objectevent.ObjectModifiedEvent object at ...>]
+
+More importantly, now our form knows about this event.
+
+  >>> form.eventCalls
+  [<zope.app.event.objectevent.ObjectModifiedEvent object at ...>]
\ No newline at end of file



More information about the Checkins mailing list