You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2009/04/16 21:00:59 UTC

svn commit: r765720 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/corelib/components/ main/resources/org/apache/tapestry5/ test/app1/nested/ test/java/org/apache/tapestry5/integration/ test/java/org/apache/tapestry5/i...

Author: hlship
Date: Thu Apr 16 19:00:58 2009
New Revision: 765720

URL: http://svn.apache.org/viewvc?rev=765720&view=rev
Log:
TAP5-624: Support for javascript callbacks on zone update

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Zone.xdoc
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Zone.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/nested/ZoneDemo.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/nested/ZoneDemo.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Zone.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Zone.java?rev=765720&r1=765719&r2=765720&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Zone.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Zone.java Thu Apr 16 19:00:58 2009
@@ -32,10 +32,15 @@
  * Often, Zones are initially invisible, in which case the visible parameter may be set to false (it defaults to true).
  * <p/>
  * When a user clicks an {@link org.apache.tapestry5.corelib.components.ActionLink} whose zone parameter is set, the
- * corresponding client-side Tapestry.Zone object is located. It will update the content of the Zone's &lt;div&gt; and
- * then invoke either a show method (if the div is not visible) or an update method (if the div is visible).  The show
- * and update parameters are the <em>names</em> of functions attached to the Tapestry.ElementEffect object.    Likewise,
- * a {@link org.apache.tapestry5.corelib.components.Form} component may also trigger an update of a client-side Zone.
+ * corresponding client-side Tapestry.ZoneManager object is located. It will update the content of the Zone's
+ * &lt;div&gt; and then invoke either a show method (if the div is not visible) or an update method (if the div is
+ * visible).  The show and update parameters are the <em>names</em> of functions attached to the Tapestry.ElementEffect
+ * object.    Likewise, a {@link org.apache.tapestry5.corelib.components.Form} component may also trigger an update of a
+ * client-side Zone.
+ * <p/>
+ * The server side event handler can return a {@link org.apache.tapestry5.Block} or a component to render as the new
+ * content on the client side. Often, re-rendering the Zone's {@linkplain #getBody() body} is useful. Multiple
+ * client-side zones may be updated by returning a {@link org.apache.tapestry5.ajax.MultiZoneUpdate}.
  * <p/>
  * Renders informal parameters, adding CSS class "t-zone" and possibly, "t-invisible".
  * <p/>
@@ -46,6 +51,9 @@
  * of the page). Failure to provide an explicit id results in a new, and non-predictable, id being generated for each
  * partial render, which will often result in client-side failures to locate the element to update when the Zone is
  * triggered.
+ * <p/>
+ * After the client-side content is updated, a client-side event is fired on the zone's element. The constant
+ * Tapestry.ZONE_UPDATED_EVENT can be used to listen to the event.
  */
 @SupportsInformalParameters
 public class Zone implements ClientElement
@@ -77,7 +85,7 @@
      * is generated for the element.
      */
     @Parameter(name = "id", defaultPrefix = BindingConstants.LITERAL)
-    private String clientId;
+    private String idParameter;
 
     @Environmental
     private RenderSupport renderSupport;
@@ -95,6 +103,8 @@
     @Inject
     private ComponentResources resources;
 
+    private String clientId;
+
     String defaultElementName()
     {
         return resources.getElementName("div");
@@ -102,8 +112,7 @@
 
     void beginRender(MarkupWriter writer)
     {
-        if (!resources.isBound("id"))
-            clientId = renderSupport.allocateClientId(resources);
+        clientId = resources.isBound("id") ? idParameter : renderSupport.allocateClientId(resources);
 
         Element e = writer.element(elementName, "id", clientId);
 
@@ -111,7 +120,7 @@
 
         e.addClassName("t-zone");
 
-        if (!visible) e.addClassName("t-invisible");
+        if (!visible) e.addClassName(CSSClassConstants.INVISIBLE);
 
         // And continue on to render the body
 
@@ -126,6 +135,12 @@
         writer.end(); // div
     }
 
+    /**
+     * The client id of the Zone; this is set when the Zone renders and will either be the value bound to the id
+     * parameter, or an allocated unique id.
+     *
+     * @return client-side element id
+     */
     public String getClientId()
     {
         return clientId;

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Zone.xdoc
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Zone.xdoc?rev=765720&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Zone.xdoc (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Zone.xdoc Thu Apr 16 19:00:58 2009
@@ -0,0 +1,78 @@
+<document>
+    <body>
+        <section name="Related Components">
+            <ul>
+                <li>
+                    <a href="AjaxFormLoop.html">AjaxFormLoop</a>
+                </li>
+                <li>
+                    <a href="FormFragment.html">FormFragment</a>
+                </li>
+            </ul>
+        </section>
+        <section name="Examples">
+
+            <subsection name="ZoneDemo.tml (partial)">
+
+                <source><![CDATA[
+<t:zone t:id="counterZone" id="counterZone">
+  <p>You have clicked the link <strong>${clickCount}</strong> times.</p>
+</t:zone>
+
+<p>
+<t:actionlink t:id="clicker" zone="counterZone">increment the count</t:actionlink>
+</p>
+
+]]></source>
+
+                <p>It's pretty standard to bind the id parameter of a zone; the zone parameter of ActionLink
+                    and Form are the<em>client-side element id</em>, not the component id. They are often,
+                    but not always, the same. Binding the id parameter ensures that a particular, fixed value
+                    is used.
+                </p>
+
+                <p>
+                    Binding the zone parameter of the ActionLink is what triggers the partial-render and update logic.
+                </p>
+
+            </subsection>
+
+            <subsection name="ZoneDemo.java">
+                <source><![CDATA[
+public class ZoneDemo
+{
+  @Property
+  @Persist
+  private int clickCount;
+
+  @InjectComponent
+  private Zone counterZone;
+
+  Object onActionFromClicker()
+  {
+    clickCount++;
+
+    return counterZone.getBody();
+  }
+}
+]]></source>
+
+                <p>
+                    The event handler method for the clicker component increments the count, then
+                    returns the body of the zone. The body will be re-rendered (reflecting the new count),
+                    and sent to the client, which will update the zone in place, and trigger and animation
+                    (by default, a simple yellow fade) to draw the user's attention.
+                </p>
+
+                <p>
+                    Not shown here, but fully valid, is to include JavaScript libraries and generate
+                    initialization JavaScript. This fully consistent with ordinary full-page renders.
+                </p>
+
+
+            </subsection>
+
+
+        </section>
+    </body>
+</document>
\ No newline at end of file

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js?rev=765720&r1=765719&r2=765720&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js Thu Apr 16 19:00:58 2009
@@ -32,16 +32,19 @@
      */
     FORM_PROCESS_SUBMIT_EVENT : "tapestry:formprocesssubmit",
 
-    /** Event, triggered on a field element, to cause observers to validate the input. Passes a memo object with
+    /** Event, fired on a field element, to cause observers to validate the input. Passes a memo object with
      * two keys: "value" (the raw input value) and "translated" (the parsed value, usually meaning a number
      * parsed from a string).  Observers may invoke Element.showValidationMessage()
      *  to identify that the field is in error (and decorate the field and show a popup error message).
      */
     FIELD_VALIDATE_EVENT : "tapestry:fieldvalidate",
 
-    /** Event, triggered on the document object, which identifies the current focus input element. */
+    /** Event, fired on the document object, which identifies the current focus input element. */
     FOCUS_CHANGE_EVENT : "tapestry:focuschange",
 
+    /** Event, fired on a zone element when the zone is updated with new content. */
+    ZONE_UPDATED_EVENT : "tapestry:zoneupdated",
+
     /** When false, the default, the Tapestry.debug() function will be a no-op. */
     DEBUG_ENABLED : false,
 
@@ -101,7 +104,7 @@
 
         document.observe("dom:loaded", hideDialog);
 
-        // An rare race condition.
+        // A rare race condition.
 
         if (Tapestry.pageLoaded)
             hideDialog.call(null);
@@ -243,12 +246,12 @@
         Tapestry.invokeLogger(message, substitutions, Tapestry.Logging.debug);
     },
 
-    invokeLogger : function(message, substitutions, blackbirdFunction)
+    invokeLogger : function(message, substitutions, loggingFunction)
     {
         if (substitutions != undefined)
             message = message.interpolate(substitutions);
 
-        blackbirdFunction.call(this, message);
+        loggingFunction.call(this, message);
     },
 
     /**
@@ -1386,8 +1389,14 @@
     },
 
     // Updates the content of the div controlled by this Zone, then
-    // invokes the show function (if not visible) or the update function (if visible).
+    // invokes the show function (if not visible) or the update function (if visible),
 
+    /**
+     * Updates the zone's content, and invokes either the update function (to highlight the change)
+     * or the show function (to reveal a hidden element). Lastly, fires the Tapestry.ZONE_UPDATED_EVENT
+     * to let listeners know that the zone was updated.
+     * @param content
+     */
     show: function(content)
     {
         this.updateElement.update(content);
@@ -1395,6 +1404,8 @@
         var func = this.element.visible() ? this.updateFunc : this.showFunc;
 
         func.call(this, this.element);
+
+        this.element.fire(Tapestry.ZONE_UPDATED_EVENT);
     },
 
     /**

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/nested/ZoneDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/nested/ZoneDemo.tml?rev=765720&r1=765719&r2=765720&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/nested/ZoneDemo.tml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/nested/ZoneDemo.tml Thu Apr 16 19:00:58 2009
@@ -68,5 +68,7 @@
         </li>
     </ul>
 
+    <div id="zone-update-message"/>
+
 
 </html>
\ No newline at end of file

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java?rev=765720&r1=765719&r2=765720&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java Thu Apr 16 19:00:58 2009
@@ -2897,6 +2897,22 @@
     }
 
     @Test
+    public void zone_updated_event_triggered_on_client()
+    {
+        start("Zone Demo");
+
+        assertText("zone-update-message", "");
+
+        click("link=Direct JSON response");
+
+        // Give it some time to process.                                                
+
+        sleep(100);
+
+        assertText("zone-update-message", "Zone updated.");
+    }
+
+    @Test
     public void hidden_field()
     {
         start("Hidden Demo", "setup");

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/nested/ZoneDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/nested/ZoneDemo.java?rev=765720&r1=765719&r2=765720&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/nested/ZoneDemo.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/nested/ZoneDemo.java Thu Apr 16 19:00:58 2009
@@ -15,6 +15,7 @@
 package org.apache.tapestry5.integration.app1.pages.nested;
 
 import org.apache.tapestry5.Block;
+import org.apache.tapestry5.RenderSupport;
 import org.apache.tapestry5.ValueEncoder;
 import org.apache.tapestry5.annotations.*;
 import org.apache.tapestry5.corelib.components.BeanEditForm;
@@ -51,6 +52,9 @@
     @InjectPage
     private SecurePage securePage;
 
+    @Environmental
+    private RenderSupport renderSupport;
+
     public String[] getNames()
     {
         return NAMES;
@@ -145,4 +149,11 @@
     {
         return securePage;
     }
+
+    void afterRender()
+    {
+        renderSupport.addScript(
+                "$('%s').observe(Tapestry.ZONE_UPDATED_EVENT, function() { $('zone-update-message').update('Zone updated.'); });",
+                output.getClientId());
+    }
 }