Author: buildbot
Date: Mon May 21 05:20:56 2018
New Revision: 1030132
Log:
Production update by buildbot for tapestry
Modified:
websites/production/tapestry/content/ajax-and-zones.html
websites/production/tapestry/content/ajax-components-faq.html
websites/production/tapestry/content/beaneditform-faq.html
websites/production/tapestry/content/cache/main.pageCache
websites/production/tapestry/content/component-events-faq.html
websites/production/tapestry/content/component-parameters.html
websites/production/tapestry/content/configuration.html
websites/production/tapestry/content/enum-parameter-recipe.html
websites/production/tapestry/content/environmental-services.html
websites/production/tapestry/content/error-page-recipe.html
websites/production/tapestry/content/extending-the-if-component.html
websites/production/tapestry/content/forms-and-form-components-faq.html
websites/production/tapestry/content/forms-and-validation.html
websites/production/tapestry/content/general-questions.html
websites/production/tapestry/content/hibernate-statistics.html
websites/production/tapestry/content/hibernate-support-faq.html
websites/production/tapestry/content/injection-faq.html
websites/production/tapestry/content/injection.html
websites/production/tapestry/content/integration-with-existing-applications.html
websites/production/tapestry/content/ioc-cookbook-basic-services-and-injection.html
websites/production/tapestry/content/ioc-cookbook-overriding-ioc-services.html
websites/production/tapestry/content/ioc-cookbook-patterns.html
websites/production/tapestry/content/ioc-cookbook-service-configurations.html
websites/production/tapestry/content/ioc-cookbook.html
websites/production/tapestry/content/javascript-faq.html
websites/production/tapestry/content/limitations.html
websites/production/tapestry/content/link-components-faq.html
websites/production/tapestry/content/maven-support-faq.html
websites/production/tapestry/content/menuleft.html
websites/production/tapestry/content/meta-programming-page-content.html
websites/production/tapestry/content/page-and-component-classes-faq.html
websites/production/tapestry/content/page-navigation.html
websites/production/tapestry/content/persistent-page-data.html
websites/production/tapestry/content/release-notes-50.html
websites/production/tapestry/content/release-notes-51.html
websites/production/tapestry/content/release-notes-52.html
websites/production/tapestry/content/release-notes-53.html
websites/production/tapestry/content/release-upgrade-faq.html
websites/production/tapestry/content/request-processing-faq.html
websites/production/tapestry/content/security-faq.html
websites/production/tapestry/content/security.html
websites/production/tapestry/content/session-storage.html
websites/production/tapestry/content/specific-errors-faq.html
websites/production/tapestry/content/tapestry-inversion-of-control-faq.html
websites/production/tapestry/content/templating-and-markup-faq.html
websites/production/tapestry/content/uploading-files.html
websites/production/tapestry/content/using-select-with-a-list.html
Modified: websites/production/tapestry/content/ajax-and-zones.html
==============================================================================
--- websites/production/tapestry/content/ajax-and-zones.html (original)
+++ websites/production/tapestry/content/ajax-and-zones.html Mon May 21
05:20:56 2018
@@ -87,11 +87,13 @@
+
+
<h3>Related Articles</h3>
<ul class="content-by-label"><li>
<div>
- <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+ <span class="icon aui-icon content-type-page"
title="Page">Page:</span> </div>
<div class="details">
<a href="ajax-and-zones.html">Ajax and Zones</a>
@@ -100,7 +102,7 @@
</div>
</li><li>
<div>
- <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+ <span class="icon aui-icon content-type-page"
title="Page">Page:</span> </div>
<div class="details">
<a href="legacy-javascript.html">Legacy JavaScript</a>
@@ -109,25 +111,25 @@
</div>
</li><li>
<div>
- <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+ <span class="icon aui-icon content-type-page"
title="Page">Page:</span> </div>
<div class="details">
- <a href="typescript.html">TypeScript</a>
+ <a href="javascript-modules.html">JavaScript
Modules</a>
</div>
</li><li>
<div>
- <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+ <span class="icon aui-icon content-type-page"
title="Page">Page:</span> </div>
<div class="details">
- <a href="coffeescript.html">CoffeeScript</a>
+ <a href="typescript.html">TypeScript</a>
</div>
</li><li>
<div>
- <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+ <span class="icon aui-icon content-type-page"
title="Page">Page:</span> </div>
<div class="details">
<a href="client-side-javascript.html">Client-Side
JavaScript</a>
@@ -136,16 +138,16 @@
</div>
</li><li>
<div>
- <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+ <span class="icon aui-icon content-type-page"
title="Page">Page:</span> </div>
<div class="details">
- <a href="javascript-modules.html">JavaScript
Modules</a>
+ <a href="coffeescript.html">CoffeeScript</a>
</div>
</li><li>
<div>
- <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+ <span class="icon aui-icon content-type-page"
title="Page">Page:</span> </div>
<div class="details">
<a href="javascript-faq.html">JavaScript FAQ</a>
@@ -154,7 +156,7 @@
</div>
</li><li>
<div>
- <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+ <span class="icon aui-icon content-type-page"
title="Page">Page:</span> </div>
<div class="details">
<a href="ajax-components-faq.html">Ajax Components
FAQ</a>
@@ -163,7 +165,7 @@
</div>
</li><li>
<div>
- <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+ <span class="icon aui-icon content-type-page"
title="Page">Page:</span> </div>
<div class="details">
<a href="component-cheat-sheet.html">Component Cheat
Sheet</a>
@@ -172,7 +174,7 @@
</div>
</li><li>
<div>
- <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+ <span class="icon aui-icon content-type-page"
title="Page">Page:</span> </div>
<div class="details">
<a href="assets.html">Assets</a>
@@ -184,14 +186,14 @@
<p>Tapestry provides easy-to-use support for <strong>Ajax</strong>, the
technique of using JavaScript to dynamically update parts of a web page with
content from the server without redrawing the whole page. With Tapestry, you
can do simple Ajax updates without having to write any JavaScript code at
all.</p><p>Ajax support is included in many <a
href="component-reference.html">built-in components</a> and <a
href="component-mixins.html">component mixins</a> via
the <code>async</code> parameter (in Tapestry 5.4+) and
the <code>zone</code> parameter (for earlier versions). Here we use an
EventLink component to trigger an Ajax update of another area of the
page:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Page or
component template (partial)</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><t:eventlink event="updateTime"
async="true">update</t:eventlink>
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml;
gutter: false; theme: Default" data-theme="Default"><t:eventlink
event="updateTime" async="true">update</t:eventlink>
...
<t:zone t:id="timeArea" id="timeArea">
The current time is ${currentTime}
</t:zone>
</pre>
</div></div><p>The corresponding Java code might look like this:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader
panelHeader pdl" style="border-bottom-width: 1px;"><b>Page or component class
(partial)</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">@Inject
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">@Inject
private AjaxResponseRenderer ajaxResponseRenderer;
@InjectComponent
@@ -209,7 +211,7 @@ void onUpdateTime()
</div></div><p>That <code>onUpdateTime</code> method is just an ordinary
Tapestry event handler, except that it uses an injected
<code>AjaxResponseRenderer</code> to tell Tapestry what zone to update when the
link is clicked.</p><p>Since Tapestry 5.4.2, you can also easily invoke
server-side event handlers using the <code>@PublishEvents</code>
annotation and the <code>t5/core/ajax</code> JavaScript function, as
explained in the "<span>Invoking server-side event handler methods from
JavaScript" section below.</span></p><h3
id="AjaxandZones-Zones">Zones</h3><p>Zones are Tapestry's approach to
performing partial page updates. A <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Zone.html">Zone
component</a> renders as an HTML element, typically a <div>, and serves
as a marker for where dynamically-updated content should be replaced. A zone is
recognizable in the DOM because it will have the attribute&#
160;<code>data-container-type=zone</code>. The client-side support for Zones
is keyed off of this attribute and value.</p><p>Starting in Tapestry 5.4 you
can use any HTML element in your template as a zone marker, by passing its
client-side id to the two-argument version of the addRender
method.</p><p><span>A Zone updated can be triggered by an EventLink, ActionLink
or Select component, or by a Form. All of these components support the
<code>async</code> and/or <code>zone</code> parameters. Clicking such a link
will invoke an event handler method on the server as normal ... except that a
</span><em>partial page response</em><span> is sent to the client, and the
content of that response is used to update the Zone's <div> in
place.</span></p><div class="navmenu" style="float:right; background:#eee;
margin:3px; padding:0 1em">
<p> <strong>JumpStart Demo:</strong><br clear="none">
<a class="external-link"
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/ajax/actionlink"
rel="nofollow">AJAX ActionLink</a></p></div><h3
id="AjaxandZones-EventHandlerReturnTypes">Event Handler Return Types</h3><p>In
a traditional request, the return value of an event handler method may used to
determine which page will render a <em>complete</em> response, and a
<em>redirect</em> may sent to the client to render the new page (as a new
request).</p><p>In contrast, with a Zone update, the return value may used to
render a <em>partial response</em> within the <em>same request</em>.</p><div
class="confluence-information-macro confluence-information-macro-note"><span
class="aui-icon aui-icon-small aui-iconfont-warning
confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>Starting in Tapestry 5.3, Ajax
event handlers typically have a void return type and use AjaxResponseRenderer
to indicate which zone to update. The AjaxResponseRe
nder approach means that the <code>zone</code> parameter's value
(oridinarily indicating which zone to update) is no longer needed. Tapestry 5.4
introduced the <code>async="true"</code> parameter to avoid having to
redundantly indicate which zone to update.</p></div></div><p>If you only have
one zone to update and don't want to use AjaxResponseRenderer, you can instead
return a value from your event handler method. The simplest case is just to
return the zone's own body:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">@Inject
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">@Inject
private Request request;
@InjectComponent
@@ -220,7 +222,7 @@ Object onActionFromSomeLink()
return myZone.getBody(); // AJAX request, return zone's own body
}</pre>
</div></div><p>The possible return values are:</p><ul><li>An injected Block or
Component to render as the response. The response will be a JSON hash, with a
"content" key whose value is the rendered markup. This is the basis for updates
with the Zone component.</li><li>The zone's own body (using Zone's getBody()
method)</li><li>null (to redraw the current page)</li><li>A <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/json/JSONObject.html">JSONObject</a>
or <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/json/JSONArray.html">JSONArray</a>,
which will be sent as the response.</li><li>A <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/StreamResponse.html">StreamResponse</a>,
which will be sent as the response.</li><li>A <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Link.html">Link</a>,
which wil
l send a redirect to the client.</li><li>A page name (as a String), or a page
class, or a page instance, which will send a redirect to the indicated
page.</li></ul><p>See <a href="page-navigation.html">Page Navigation</a>
for full descriptions of the above.</p><h3
id="AjaxandZones-GracefulDegradation">Graceful Degradation</h3><p>Users who do
not have JavaScript enabled may click EventLinks (or ActionLinks, or Forms)
that are configured to update a Zone. When that occurs, the request will still
be sent to the server, but Tapestry will handle it as a <em>traditional</em>
request.</p><p>This happens automatically when your event handler method has a
void return type.</p><p>However, to support graceful degradation when your
event handler method has a <em>non-void</em> return type, you should detect
non-Ajax requests and return a traditional response, typically null to redraw
the whole page. This is accomplished by injecting the <a class="external-link"
href="http://tapestry.apach
e.org/current/apidocs/org/apache/tapestry5/services/Request.html">Request</a>
object, and invoking the isXHR() method. This value will be true for Ajax
requests, and false for traditional request.</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">@Inject
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">@Inject
private Request request;
@InjectComponent
@@ -235,7 +237,7 @@ Object onActionFromSomeLink()
</div></div><h3 id="AjaxandZones-MultipleZoneUpdates">Multiple Zone
Updates</h3><p></p><div class="navmenu" style="float:right; background:#eee;
margin:3px; padding:0 1em">
<p> <strong>JumpStart Demo:</strong><br clear="none">
<a class="external-link"
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/ajax/multiplezoneupdate"
rel="nofollow">AJAX Multiple Zone Update</a></p></div>An event handler often
needs to update multiple zones on the client side. To accomplish this, use an
<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ajax/AjaxResponseRenderer.html">AjaxResponseRenderer</a>,
indicating the zones to update. You must know the client-side id for each zone
to update (the best way for this is to lock down the zone's id using the id
parameter of the Zone component).<p><em>AjaxResponseRenderer was introduced in
Tapestry 5.3. For Tapestry 5.2 and earlier, return a <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ajax/MultiZoneUpdate.html">MultiZoneUpdate</a>
object instead.</em></p><p>The renderer for each zone can be the zone itself,
a block, a component, a <a class="external-link" hr
ef="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Renderable.html">Renderable</a>
or a <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/runtime/RenderCommand.html">RenderCommand</a>
... or an object, such as String, that can be coerced to either of
these.</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>For
Tapestry 5.3 and later</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">@InjectComponent
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">@InjectComponent
private Zone userInput;
@InjectComponent
@@ -251,22 +253,22 @@ void onActionFromRegister()
}
</pre>
</div></div><p><span>This example assumes that there are two zones,
"userInput" and "helpPanel", somewhere in the rendered page, waiting to receive
the updated content.</span></p><p><span> </span></p><div
class="confluence-information-macro confluence-information-macro-note"><span
class="aui-icon aui-icon-small aui-iconfont-warning
confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>In this example, the Zone receives
the update but does not provide any content. That's OK, the other client-side
elements (<code>userInput</code> and <code>helpPanel</code>) will be updated,
and the zone's content left unchanged.</p></div></div><p>This demonstrates why
it is necessary for the developer to specify a particular client-side id for
Zone components; if they were dynamically allocated ids, as is typical in most
other elements, it would be impossible for this code to know what client-side
id was used for the Zone.</p><h3 id="AjaxandZones-ZoneComponen
tIdvs.ZoneElementId">Zone Component Id vs. Zone Element Id</h3><p>Like all
Tapestry components, Zones have a component id, specified using the
<code>t:id</code> attribute. If you do not assign a component id, a unique id
is assigned by Tapestry.</p><p>However, to coordinate things on the client
side, it is necessary for components that wish to update the zone know the
<em>client-side element id</em>. This is specified with the <code>id</code>
parameter of the Zone component. If the <code>id</code> parameter is not bound,
then a unique value (for the current page and render) is generated by Tapestry
and this value is difficult to predict. (The actual value will be available as
the <code>clientId</code> property of the Zone component
itself.)</p><p>Remember that the component id (<code>t:id</code>) is used to
<em>inject</em> the Zone component into the containing page or component. The
client-side id (<code>id</code>) is used on the client side to orchestrate
requests and updates. You
will often seen the following construct:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><t:zone t:id="myZone" id="myzone"> ...
</t:zone>
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml;
gutter: false; theme: Default" data-theme="Default"><t:zone t:id="myZone"
id="myzone"> ... </t:zone>
</pre>
</div></div><h3 id="AjaxandZones-TheContainingZone(zone="^")">The
Containing Zone (zone="^")</h3><p><em><strong>Since 5.2</strong></em></p><p>If
the Form or Link is enclosed by the Zone itself, and you're using
the <code>zone</code> parameter instead of the <code>async</code>
parameter, then the <code>zone</code> parameter may be set to the special
value <strong><code>^</code></strong><code> (the carat)</code>. The zone
is found – on the client side – by searching up form the
form or link element for the first enclosing element that is a Zone. In this
way, the client-side coordination can occur without having to know what the
specific client-side id of the Zone is. Because of this, in some cases it is no
longer necessary to specify the Zone's <code>id</code> parameter.</p><h3
id="AjaxandZones-AnUpdatedivwithinaZonediv(Tapestry5.3andearlier)">An Update
div within a Zone div (Tapestry 5.3 and earlier)</h3><p><em><strong>Deprecat
ed</strong><strong>:</strong> This feature is removed starting with Tapestry
5.4</em></p><p>In many situations, a Zone is a kind of "wrapper" or "container"
for dynamic content; one that provides a look and feel ... a bit of wrapping
markup to create a border. In that situation, the Zone <div> may contain
an update <div>.</p><p>An Update <div> is specifically a
<div> element marked with the CSS class "t-zone-update", <em>inside</em>
the Zone's <div>.</p><p>If an Update div exists within a Zone div, then
when Tapestry updates a zone only the update <div>'s content will be
changed, rather than the entire Zone <div>.</p><p>The show and update
functions (see Zone Functions, below) apply to the Zone <div>, not just
the update <div>.</p><h3
id="AjaxandZones-ZoneEffectFunctions(Tapestry5.3andearlier)">Zone Effect
Functions (Tapestry 5.3 and
earlier)</h3><p><strong><em>Deprecated:</em></strong> This feature refers to
client-side logic on
ly present in Tapestry 5.3 or earlier. For 5.4, there are client-side events
that are triggered before and after changes to the Zone; listeners on those
events can trigger whatever animations they like.</p><p>A Zone may be initially
visible or invisible. When a Zone is updated, it is made visible if not
currently so. This is accomplished via a function on the Tapestry.ElementEffect
client-side object. By default, the show() function is used for this purpose.
If you want Tapestry to call a different Tapestry.ElementEffect function when
updates occur, specify its name with the zone's show parameter.</p><p>If a Zone
is already visible, then a different effect function is used to highlight the
change. By default, the highlight() function is called, which performs a yellow
fade to highlight that the content of the Zone has changed. Alternatively, you
can specify a different effect function with the Zone's update
parameter:</p><div class="table-wrap"><table class="confluenceTable"><tbody>
<tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Tapestry.ElementEffect
Function</p></th><th colspan="1" rowspan="1"
class="confluenceTh"><p>Result</p></th></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>highlight()</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>(the default) highlight changes to an already-visible
zone</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>show()</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>make the zone visible if it isn't already
visible</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>slidedown()</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>scroll the content down</p></td></tr><tr><td
colspan="1" rowspan="1" class="confluenceTd"><p>slideup()</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>slide the content back up
(opposite of slidedown)</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>fade()</p></td><td colspan="1" ro
wspan="1" class="confluenceTd"><p>fade the content out (opposite of
show)</p></td></tr></tbody></table></div><p>To have Tapestry update a zone
without the usual yellow highlight effect, just specify "show" for the update
parameter:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><t:zone t:id="myZone" t:update="show"></pre>
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml;
gutter: false; theme: Default" data-theme="Default"><t:zone t:id="myZone"
t:update="show"></pre>
</div></div><p>You may also define and use your own JavaScript effect function
(with lower-case names), like this:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: js; gutter: false; theme: Default"
style="font-size:12px;">Tapestry.ElementEffect.myeffectname =
function(element){ YourJavascriptCodeGoesHere; };
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: js;
gutter: false; theme: Default"
data-theme="Default">Tapestry.ElementEffect.myeffectname = function(element){
YourJavascriptCodeGoesHere; };
</pre>
</div></div><h3 id="AjaxandZones-ZoneLimitations">Zone
Limitations</h3><p>Unlike many other situations, Tapestry relies on you to
specify useful and unique ids to Zone components, then reference those ids
inside EventLink (or ActionLink, or Form) components. Using Zone components
inside any kind of loop may cause additional problems, as Tapestry will
<em>uniqueify</em> the client id you specify (appending an index
number).</p><p>If you create a component that contains a zone, and you use that
component in a loop, you'll likely need to set the client-side id like
this:</p><p> </p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><t:zone t:id="myzone"
id="prop:componentResources.id"></pre>
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml;
gutter: false; theme: Default" data-theme="Default"><t:zone t:id="myzone"
id="prop:componentResources.id"></pre>
</div></div><p> </p><p>See <a class="external-link"
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/ajax/components1"
rel="nofollow">this JumpStart Example</a> for details.</p><p>The show and
update function names (Tapestry 5.3 and earlier only) are converted to lower
case; all the methods of Tapestry.ElementEffect should have all lower-case
names. Because client-side JavaScript is so fluid (new methods may be added to
existing objects), Tapestry makes no attempt to validate the function names ...
however, if the names are not valid, then the default show and highlight
methods will be used.</p><p>Zones may only be used inside the <em>body</em> of
a page, not the head<em>.</em></p><h3 id="AjaxandZones-MoreInformation">More
Information</h3><p>For examples of extending a Form with a Zone and updating
multiple zones at once, see the <a href="ajax-components-faq.html">Ajax
Components FAQ</a>.</p><p>There are also a number of Ajax-related examples at
the  
<a class="external-link"
href="http://jumpstart.doublenegative.com.au/jumpstart/" rel="nofollow"><span
class="confluence-link">Tapestry JumpStart</span></a> site.</p><p><span
class="confluence-anchor-link" id="AjaxandZones-autocomplete"></span></p><h2
id="AjaxandZones-AutocompleteMixin">Autocomplete Mixin</h2><p></p><div
class="navmenu" style="float:right; background:#eee; margin:3px; padding:0 1em">
<p> <strong>JumpStart Demo:</strong><br clear="none">
<a class="external-link"
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/ajax/autocompletemixin"
rel="nofollow">Autocomplete Mixin</a></p></div>The <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/mixins/Autocomplete.html">Autocomplete</a>
mixin exists to allow a text field to query the server for completions for a
partially entered phrase. It is often used in situations where the field exists
to select a single value from a large set, too large to successfully download
to the client as a drop down list; for example, when the number of values to
select from is numbered in the thousands.<p>Autocomplete can be added to an
existing text field:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> <t:textfield t:id="accountName"
t:mixins="autocomplete" size="100"/>
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default"> <t:textfield
t:id="accountName" t:mixins="autocomplete" size="100"/>
</pre>
</div></div><p>The mixin can be configured in a number of ways, see the <a
href="component-reference.html">component reference</a>.</p><p>When the user
types into the field, the client-side JavaScript will send a request to the
server to get completions.</p><p>You must write an event handler to provide
these completions. The name of the event is "providecompletions". The context
is the partial input value, and the return value will be converted into the
selections for the user.</p><p>For example:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> List<String>
onProvideCompletionsFromAccountName(String partial)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default"> List<String>
onProvideCompletionsFromAccountName(String partial)
{
List<Account> matches = accountDAO.findByPartialAccountName(partial);
@@ -281,7 +283,7 @@ void onActionFromRegister()
}
</pre>
</div></div><p>This presumes that <code>findByPartialAccountName()</code> will
sort the values, otherwise you will probably want to sort them. The
Autocomplete mixin does <em>not</em> do any sorting.</p><p>You can return an
object array, a list, even a single object. You may return objects instead of
strings ... and <code>toString()</code> will be used to convert them into
client-side strings.</p><p> </p><h2
id="AjaxandZones-Invokingserver-sideeventhandlermethodsfromJavaScript">Invoking
server-side event handler methods from JavaScript</h2><p>Tapestry 5.4.2
introduced an API which makes it easy for server-side events to be invoked from
JavaScript. On the server-side, you first need to annotate the event handler
methods you want to expose with
the <code>@PublishEvent</code> annotation. Then, in JavaScript, all
you need to do is to call the existing <code><a class="external-link"
href="http://tapestry.apache.org/current/coffeescript/ajax.html">t5/core/ajax</a></co
de> function, but with slightly different parameters.</p><p><code>The
t5/core/ajax</code> function has two parameters: <code>url</code>
and <code>options</code>. Prior to Tapestry 5.4.2, the first one was
difficult to get when doing AJAX requests to event handler methods. You needed
to inject <code>ComponentResources in your component class</code>,
call <code>componentResources.createEventLink()</code> for each event
handler method, then pass all this information back to the browser through one
of the <code>JavaScriptSupport</code> methods. For Tapestry 5.4.2 and
later, your JavaScript code only needs to know the event name (also called
<em>event type</em>) and optionally indicate a DOM element to be used as a
starting point for finding the event URL.</p><p>All event data is stored
in <code>data-componenent-events</code> attributes. For page classes, the
attribute is added to the <code><body></code> element. For
components, it's added to
the first element rendered by the component. Given an HTML element, the
search is performed in the following order until information for the given
event is first found:</p><ol><li>The element itself</li><li>The element's
previous siblings, closest first (bottom-up)</li><li>The element's
parents</li><li>The page's <<code>body></code>
element</li></ol><p> </p><p>Here's one example:</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">public class PublishEventDemoComponent
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">public class
PublishEventDemoComponent
{
@OnEvent("answer")
@PublishEvent
@@ -298,12 +300,12 @@ void onActionFromRegister()
</pre>
</div></div><p>Notice that <code>answer()</code>
and <code>onAction()</code> are ordinary event handlers, with nothing
specific besides the <code>@PublishEvent</code> annotation.</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><div id="component"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml;
gutter: false; theme: Default" data-theme="Default"><div id="component"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<p id="componentParagraph">I'm a component</p>
<p id="result">(no result yet)</p>
</div></pre>
</div></div><p>The template also has nothing special. When rendered, the
component's events information is placed in the outer <<code>div></code>
(<code>id="component"). </code></p><p>We want to update the text
of <code><p id="result"></code> with the value of
the <code>origin</code> property of the returned JSON object when that
element itself is clicked, so here's our JavaScript code, supposing we want to
trigger the <code>answer</code> event:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: js; gutter: true; theme: Default"
style="font-size:12px;">require(["t5/core/ajax", "jquery"], function (ajax, $) {
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: js;
gutter: true; theme: Default" data-theme="Default">require(["t5/core/ajax",
"jquery"], function (ajax, $) {
// Creating a callback to be invoked with <p id="result"> is clicked.
$('#result').click(function() {
ajax('answer', {
Modified: websites/production/tapestry/content/ajax-components-faq.html
==============================================================================
--- websites/production/tapestry/content/ajax-components-faq.html (original)
+++ websites/production/tapestry/content/ajax-components-faq.html Mon May 21
05:20:56 2018
@@ -78,14 +78,14 @@
<div id="content">
<div id="ConfluenceContent"><h1
id="AjaxComponentsFAQ-AjaxComponents">Ajax Components</h1><p>Main article: <a
href="ajax-and-zones.html">Ajax and Zones</a></p><h2
id="AjaxComponentsFAQ-Contents">Contents</h2><p><style
type="text/css">/*<![CDATA[*/
-div.rbtoc1523334038444 {padding: 0px;}
-div.rbtoc1523334038444 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1523334038444 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1526880011220 {padding: 0px;}
+div.rbtoc1526880011220 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1526880011220 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1523334038444">
+/*]]>*/</style></p><div class="toc-macro rbtoc1526880011220">
<ul class="toc-indentation"><li><a
href="#AjaxComponentsFAQ-DoIhavetospecifybothidandt:idforZonecomponents?">Do I
have to specify both id and t:id for Zone components?</a></li><li><a
href="#AjaxComponentsFAQ-HowdoIupdatethecontentofaZonefromaneventhandlermethod?">How
do I update the content of a Zone from an event handler method?</a></li><li><a
href="#AjaxComponentsFAQ-HowtoIupdatemultiplezonesinasingleeventhandler?">How
to I update multiple zones in a single event handler?</a></li><li><a
href="#AjaxComponentsFAQ-What'sthatweirdnumberinthemiddleoftheclientidsafteraZoneisupdated?">What's
that weird number in the middle of the client ids after a Zone is
updated?</a></li><li><a
href="#AjaxComponentsFAQ-WhydoIsometimesgettheexception"Therenderedcontentdidnotincludeanyelementsthatallowforthepositioningofthehiddenformfield'selement."whenrenderinganemptyZone?">Why
do I sometimes get the exception "The rendered content did not include any
elements that allow for the positioni
ng of the hidden form field's element." when rendering an empty
Zone?</a></li></ul>
</div><h2
id="AjaxComponentsFAQ-DoIhavetospecifybothidandt:idforZonecomponents?">Do I
have to specify both <code>id</code> and <code>t:id</code> for Zone
components?</h2><p>The examples for the Zone component (in the Component
Reference) consistently specify both <code>id</code> and <code>t:id</code> and
this is probably a good idea.</p><p>Generally speaking, if you don't specify
the client-side id (the <code>id</code> attribute), it will be the same as the
Tapestry component id (<code>t:id</code>).</p><p>However, there are any number
of exceptions to this rule. The Zone may be rendering inside a Loop (in which
case, each rendering will have a unique client side id). The Zone may be
rendering as part of a partial page render, in which case, a random unique id
is inserted into the id. There are other examples where Tapestry component ids
in nested components may also clash.</p><p>The point is, to be sure, specify
the exact client id. This will be the value for the <code>zone</code> p
arameter of the triggering component (such as a Form, PageLink, ActionLink,
etc.).</p><h2
id="AjaxComponentsFAQ-HowdoIupdatethecontentofaZonefromaneventhandlermethod?">How
do I update the content of a Zone from an event handler method?</h2><p>When a
client-side link or form triggers an update, the return value from the event
handler method is used to construct a partial page response; this partial page
response includes markup content that is used to update the Zone's client-side
<code><div></code> element.</p><p>Where does that content come from? You
inject it into your page.</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><t:zone id="search" t:id="searchZone">
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml;
gutter: false; theme: Default" data-theme="Default"><t:zone id="search"
t:id="searchZone">
<t:form t:id="searchForm" zone="searchZone">
<t:textfield t:id="query" size="20"/>
<input type="submit" value="Search"/>
@@ -99,7 +99,7 @@ div.rbtoc1523334038444 li {margin-left:
</t:block>
</pre>
</div></div><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> @Inject
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default"> @Inject
private Block searchResults;
Object onSuccessFromSearchForm()
@@ -110,7 +110,7 @@ div.rbtoc1523334038444 li {margin-left:
}
</pre>
</div></div><p>So, when the search form is submitted, the resulting search
hits are collected. In the same request, the searchResults block is rendered,
package, and sent to the client. The form inside the client-side Zone
<code><div></code> is replaced with the list of hits.</p><p>In many
cases, you just want to re-render the Zone itself, to display updated content.
In that case, you don't need a separate <code><t:block></code>, instead
you can use @InjectComponent to inject the Zone object itself, and return the
Zone's body:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> @InjectComponent
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default"> @InjectComponent
private Zone statusZone;
Object onActionFromUpdateStatus()
@@ -119,7 +119,7 @@ div.rbtoc1523334038444 li {margin-left:
}
</pre>
</div></div><h2
id="AjaxComponentsFAQ-HowtoIupdatemultiplezonesinasingleeventhandler?">How to I
update multiple zones in a single event handler?</h2><p>To do this, you must
know, on the server, the client ids of each Zone. That's one of the reasons
that you will generally set the Zone's client id (via the Zone's id parameter),
rather than let Tapestry assign a client id for you.</p><p>From the event
handler method, instead of returning a Block or a Component, return a
multi-zone update:</p><p> </p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeHeader panelHeader pdl"
style="border-bottom-width: 1px;"><b>Multiple Zone Update (5.3+)</b></div><div
class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> @Inject
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default"> @Inject
private Block searchResults;
@Inject
@@ -138,13 +138,13 @@ div.rbtoc1523334038444 li {margin-left:
}
</pre>
</div></div><p>Note: Users of Tapestry 5.2 and earlier (which didn't support
AjaxResponseRenderer) must replace that last line with: <code>return new
MultiZoneUpdate("results", searchResults).add("status",
statusBlock);</code></p><p>AjaxResponseRenderer adds other useful commands as
well. It also has the advantage that a simple return value can be returned to
render content for the Zone that triggered the request.</p><h2
id="AjaxComponentsFAQ-What'sthatweirdnumberinthemiddleoftheclientidsafteraZoneisupdated?">What's
that weird number in the middle of the client ids after a Zone is
updated?</h2><p>You might start with markup in your template for a component
such as a TextField:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"> <t:textfield t:id="firstName"/>
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml;
gutter: false; theme: Default" data-theme="Default"> <t:textfield
t:id="firstName"/>
</pre>
</div></div><p>When the component initially renders as part of a full page
render, you get a sensible bit of markup:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"> <input id="firstName" name="firstName"
type="text">
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml;
gutter: false; theme: Default" data-theme="Default"> <input id="firstName"
name="firstName" type="text">
</pre>
</div></div><p>But when the form is inside a Zone and rendered as part of a
zone update, the ids get weird:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"> <input id="firstName_12a820cc40e"
name="firstName" type="text">
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml;
gutter: false; theme: Default" data-theme="Default"> <input
id="firstName_12a820cc40e" name="firstName" type="text">
</pre>
</div></div><p>What's happening here is that Tapestry is working to prevent
unwanted id clashes as part of the page update. In an HTML document, each
<code>id</code> is expected to be unique; most JavaScript is keyed off of the
<code>id</code> field, for instance.</p><p>In a full page render, components
don't just use their component id (<code>t:id</code>) as their client id;
instead they use the <code>JavaScriptSupport</code> environmental to allocate a
unique id. When there's no loops or conflicts, the client id matches the
component id.</p><p>When the component is inside a loop, a suffix is appended:
<code>firstName</code>, <code>firstName_0</code>, <code>firstName_1</code>,
etc.</p><p>When the component is rendered as part of an Ajax partial page
update, the rules are different. Since Tapestry doesn't know what content has
been rendered onto the page previously, it can't use its normal tricks to
ensure that ids are unique.</p><p>Instead, Tapestry creates a random-ish unique
id s
uffix, such as "12a820cc40e" in the example; this suffix is appended to all
allocated ids to ensure that they do not conflict with previously rendered
ids.</p><h2
id="AjaxComponentsFAQ-WhydoIsometimesgettheexception"Therenderedcontentdidnotincludeanyelementsthatallowforthepositioningofthehiddenformfield'selement."whenrenderinganemptyZone?">Why
do I sometimes get the exception "The rendered content did not include any
elements that allow for the positioning of the hidden form field's element."
when rendering an empty Zone?</h2><p>As part of Tapestry's form processing, it
must write a hidden input element with information needed when the form is
submitted. Since the content of a Zone may be changed or removed, a hidden
field is created just for the Zone, separate from the rest of the enclosing
form.</p><p>At the same time, Tapestry wants to position the <input>
field in a valid location, and HTML defines some constraints for that; an input
field must appear inside a &l
t;p> or <div> element. If your zone is initially empty, there's no
place to put the hidden element, and Tapestry will complain.</p><p>The solution
is simple: just add a <div> element to the body of the zone. This<span>
ensures that there's a place for the hidden input field.  An empty
<div> element (even one containing a hidden form field) will not affect
page layout.</span></p></div>
</div>
Modified: websites/production/tapestry/content/beaneditform-faq.html
==============================================================================
--- websites/production/tapestry/content/beaneditform-faq.html (original)
+++ websites/production/tapestry/content/beaneditform-faq.html Mon May 21
05:20:56 2018
@@ -78,14 +78,14 @@
<div id="content">
<div id="ConfluenceContent"><h1
id="BeanEditFormFAQ-BeanEditForm">BeanEditForm</h1><p>Main Article: <a
href="beaneditform-guide.html">BeanEditForm Guide</a></p><h2
id="BeanEditFormFAQ-Contents">Contents</h2><p><style
type="text/css">/*<![CDATA[*/
-div.rbtoc1523334062326 {padding: 0px;}
-div.rbtoc1523334062326 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1523334062326 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1526880022595 {padding: 0px;}
+div.rbtoc1526880022595 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1526880022595 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1523334062326">
+/*]]>*/</style></p><div class="toc-macro rbtoc1526880022595">
<ul class="toc-indentation"><li><a
href="#BeanEditFormFAQ-WhydoIgetexceptionsaboutinstantiatingabeanwhenusingBeanEditForm?">Why
do I get exceptions about instantiating a bean when using
BeanEditForm?</a></li><li><a
href="#BeanEditFormFAQ-What'sthedifferencebetweenBeanEditorandBeanEditForm?">What's
the difference between BeanEditor and BeanEditForm?</a></li><li><a
href="#BeanEditFormFAQ-HowdoIcustomizethelayoutoftheBeanEditForm?">How do I
customize the layout of the BeanEditForm?</a></li></ul>
</div><h2
id="BeanEditFormFAQ-WhydoIgetexceptionsaboutinstantiatingabeanwhenusingBeanEditForm?">Why
do I get exceptions about instantiating a bean when using
BeanEditForm?</h2><p>When you render a BeanEditForm, or when the rendered form
is submitted, Tapestry must instantiate an instance of the object to be edited.
This occurs when the BeanEditForm's <code>object</code> parameter is bound to
null: Tapestry instantiates an instance of the property type so that the
BeanEditForm has an object to read default values from, or to push submitted
values into.</p><p>By default, this uses the standard <a
href="injection-in-detail.html">injection mechanism</a>, which means that
Tapestry will identify the public constructor with the most parameters, and
attempt to find objects and other objects for each constructor
parameter.</p><p>There's two ways to fine tune this so you don't get
errors:</p><ul><li>Place an @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apac
he/tapestry5/ioc/annotations/Inject.html">Inject</a> annotation on the correct
constructor to use (often, the constructor with no parameters).</li></ul><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">public class MyBean {
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">public class MyBean {
@Inject
public MyBean() { ... }
@@ -97,7 +97,7 @@ div.rbtoc1523334062326 li {margin-left:
}
</pre>
</div></div><ul><li>Provide an event handler method for the "prepare" event,
and put an instantiated instance into the property.</li></ul><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">public class MyPage {
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java;
gutter: false; theme: Default" data-theme="Default">public class MyPage {
@Property
public MyBean myBean;
Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.
Modified: websites/production/tapestry/content/component-events-faq.html
==============================================================================
--- websites/production/tapestry/content/component-events-faq.html (original)
+++ websites/production/tapestry/content/component-events-faq.html Mon May 21
05:20:56 2018
@@ -78,11 +78,11 @@
<div id="content">
<div id="ConfluenceContent"><h1
id="ComponentEventsFAQ-ComponentEvents">Component Events</h1><p>Main Article:
<a href="component-events.html">Component Events</a></p><h2
id="ComponentEventsFAQ-Contents">Contents</h2><p><style
type="text/css">/*<![CDATA[*/
-div.rbtoc1523334056342 {padding: 0px;}
-div.rbtoc1523334056342 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1523334056342 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1526880022307 {padding: 0px;}
+div.rbtoc1526880022307 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1526880022307 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1523334056342">
+/*]]>*/</style></p><div class="toc-macro rbtoc1526880022307">
<ul class="toc-indentation"><li><a
href="#ComponentEventsFAQ-WhydoesTapestrysendaredirectafteraformissubmitted?">Why
does Tapestry send a redirect after a form is submitted?</a></li><li><a
href="#ComponentEventsFAQ-IspecifiedazoneinmyActionLink/EventLink,sowhydoesn'tmyeventfireviaajax(request.isXHR()isfalse)?">I
specified a zone in my ActionLink/EventLink, so why doesn't my event fire via
ajax (request.isXHR() is false)?</a></li></ul>
</div><h2
id="ComponentEventsFAQ-WhydoesTapestrysendaredirectafteraformissubmitted?">Why
does Tapestry send a redirect after a form is submitted?</h2><p>This is an
extension of the <a class="external-link"
href="http://en.wikipedia.org/wiki/Post/Redirect/Get"
rel="nofollow">Post/Redirect/Get</a> approach. It ensures that after an
operation that updates server-side state, such as a form submission, if the
user resubmits the resulting page, the operation is <strong>not</strong>
performed a second time; instead just the results of the operation, reflecting
the changed server-side state, is re-rendered.</p><p>This has the unwanted
requirement that any data needed to render the response must persist between
the event request (the form submission) and the render request; this often
means that fields must be annotated with @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Persist.html">Persist</a>.