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 <div> 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
+ * <div> 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());
+ }
}