Author: buildbot
Date: Fri Mar 4 02:19:35 2016
New Revision: 981772
Log:
Production update by buildbot for tapestry
Modified:
websites/production/tapestry/content/cache/main.pageCache
websites/production/tapestry/content/component-events.html
Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.
Modified: websites/production/tapestry/content/component-events.html
==============================================================================
--- websites/production/tapestry/content/component-events.html (original)
+++ websites/production/tapestry/content/component-events.html Fri Mar 4
02:19:35 2016
@@ -163,13 +163,17 @@
this.value = value;
}
</pre>
-</div></div><p>The <code>value</code> attribute of the OnEvent annotation is
the name of the event to match. The default event type is "action"; the
ActionLink and Form components each use this event type. Alternatively, we
could have used an EventLink component, in which case the name of the event is
determined by the element's ID, rather than being "action".</p><p>If you omit
the <code>component</code> part of the OnEvent annotation, then you'll receive
notifications from <em>all</em> contained components, possibly including nested
components (due to event bubbling).</p><div class="confluence-information-macro
confluence-information-macro-tip"><span class="aui-icon aui-icon-small
aui-iconfont-approve confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>You should usually specify exactly
which component(s) you wish to receive events from. Using @OnEvent on a method
and not specifying a specific component id means that the method will be invoke
d for events from <em>any</em> component.</p></div></div><p>Event handler
methods are normally given package-private visibility, to support testing,
although technically they may have any visibility (even private).</p><p>A
single event handler method may receive notifications from many different
components.</p><p>As elsewhere, the comparison of event type and component id
is case-insensitive.</p><h2 id="ComponentEvents-MethodNamingConvention">Method
Naming Convention</h2><p>As an alternative to the use of annotations, you may
name your event handling methods following a certain convention, and Tapestry
will find and invoke your methods just as if they were annotated.</p><p>This
style of event handler methods start with the prefix "on", followed by the name
of the action. You may then continue by adding "From" and a capitalized
component id (remember that Tapestry is case insensitive about event names and
component ids). So, for example, a method named onActionFromSelect(), if it exi
sts, is invoked whenever an <code>Action</code> event is emitted by the
<code>select</code> component.</p><p>The previous example may be rewritten
as:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+</div></div><p>For the OnEvent annotation, the <em><code>value</code></em>
attribute identifies the name of the event to match. We specified "action"
because the ActionLink component emits the "action" event, as noted in the
Component Events section of its <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/ActionLink.html">javadocs</a>.</p><p>Alternatively,
we can use the EventLink component, in which case the name of the event is
determined by us – either through the "event" parameter or the element's
ID:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>An
EventLink that emits the "clear" event</b></div><div class="codeContent
panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><t:eventlink event="clear"
context="index">${index}</a></pre>
+</div></div><p>which is equivalent to:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeHeader panelHeader pdl"
style="border-bottom-width: 1px;"><b>An EventLink that emits the "clear"
event</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><a t:type="eventlink" t:id="clear"
context="index">${index}</a></pre>
+</div></div><p>Note that if you omit the <code>component</code> part of the
OnEvent annotation, then you'll receive notifications from <em>all</em>
contained components, possibly including nested components (due to event
bubbling).</p><div class="confluence-information-macro
confluence-information-macro-tip"><span class="aui-icon aui-icon-small
aui-iconfont-approve confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>You should usually specify exactly
which component(s) you wish to receive events from. Using @OnEvent on a method
and not specifying a specific component id means that the method will be
invoked for events from <em>any</em> component.</p></div></div><p>To support
testing, it's a common practice to give event handler methods
<em>package-private</em> visibility, as in the examples on this page, although
technically they may have any visibility (even private).</p><p>A single event
handler method may receive notifications from many dif
ferent components.</p><p>As elsewhere, the comparison of event type and
component id is case-insensitive.</p><h2
id="ComponentEvents-MethodNamingConvention">Method Naming Convention</h2><p>As
an alternative to the use of annotations, you may name your event handling
methods following a certain convention, and Tapestry will find and invoke your
methods just as if they were annotated.</p><p>This style of event handler
methods start with the prefix "on", followed by the name of the action. You may
then continue by adding "From" and a capitalized component id (remember that
Tapestry is case insensitive about event names and component ids). So, for
example, a method named onActionFromSelect(), if it exists, is invoked whenever
an <code>Action</code> event is emitted by the <code>select</code>
component.</p><p>The previous example may be rewritten as:</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;"> void onActionFromSelect(int value)
{
this.value = value;
}
</pre>
-</div></div><div class="confluence-information-macro
confluence-information-macro-information"><span class="aui-icon aui-icon-small
aui-iconfont-info confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>Note from Howard: I've found that
I prefer the naming convention approach, and reserve the annotation just for
situations that don't otherwise fit.</p></div></div><h2
id="ComponentEvents-MethodReturnValues">Method Return Values</h2><p>Main
Article: <a href="page-navigation.html">Page Navigation</a></p><p>For page
navigation events (originating in components such as EventLink, ActionLink and
Form), the value returned from an event handler method determines how Tapestry
will render a response.</p><ul><li><strong>Null</strong>: For no value, or
null, the current page (the page containing the component) will render the
response.</li><li><strong>Page</strong>: For the name of a page, or a page
class or page instance, a render request URL will be con
structed and sent to the client as a redirect to that
page.</li><li><strong>URL</strong>: For a java.net.URL, a redirect will be sent
to the client. (In Tapestry 5.3.x and earlier, this only works for non-Ajax
requests.)</li><li><strong>Zone body</strong>: In the case of an Ajax request
to update a zone, the component event handler will return the new zone body,
typically via an injected component or
block.</li><li><strong>HttpError</strong>: For an <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/HttpError.html">HttpError</a>,
an error response is sent to the client.</li><li><strong>Link</strong>: For a
<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Link.html">Link</a>,
a redirect is sent to the client.</li><li><strong>Stream</strong>: For a <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/StreamResponse.html">StreamResponse</a>,
a
stream of data is sent to the client</li></ul><p>See <a
href="page-navigation.html">Page Navigation</a> for more details.</p><h2
id="ComponentEvents-MultipleMethodMatches">Multiple Method Matches</h2><p>In
some cases, there may be multiple event handler methods matching a single
event. In that case, Tapestry invokes them in the following
order:</p><ul><li>Base class methods before sub-class methods.</li><li>Matching
methods within a class in alphabetical order.</li><li>For a single method name
with multiple overrides, by number of parameters, descending.</li></ul><p>Of
course, ordinarily would you <em>not</em> want to create more than one method
to handle an event.</p><p>When a sub-class overrides an event handler method of
a base class, the event handler method is only invoked once, along with any
other base class methods. The subclass can change the <em>implementation</em>
of the base class method via an override, but can't change the <em>timing</em>
of when that method is invoke
d. See <a class="external-link"
href="https://issues.apache.org/jira/browse/TAP5-51">issue TAP5-51</a>.</p><h1
id="ComponentEvents-EventContext">Event Context</h1><p>The context values (the
context parameter to the EventLink or ActionLink component) can be any object.
However, only a simple conversion to string occurs. (This is in contrast to
Tapestry 4, which had an elaborate type mechanism with the odd name
"DataSqueezer".)</p><p>Again, whatever your value is (string, number, date), it
is converted into a plain string. This results in a more readable URL.</p><p>If
you have multiple context values (by binding a list or array of objects to the
<em>context</em> parameter of the EventLink or ActionLink), then each one, in
order, will be added to the URL.</p><p>When an event handler method is invoked,
the strings are converted back into values, or even objects. A <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ValueEncoder.html">ValueEnc
oder</a> is used to convert between client-side strings and server-side
objects. The <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ValueEncoderSource.html">ValueEncoderSource</a>
service provides the necessary value encoders.</p><p>As shown in the example
above, most of the parameters passed to the event handler method are derived
from the values provided in the event context. Each successive method parameter
matches against a value provided in the event context (the context parameter of
the ActionLink component; though many components have a similar context
parameter).</p><p>In some cases, it is desirable to have direct access to the
context (for example, to adapt to cases where there are a variable number of
context values). The context values may be passed to an event handler method as
parameter of the following types:</p><ul><li><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestr
y5/EventContext.html">EventContext</a></li><li>Object[]</li><li>List<Object></li></ul><p>The
latter two should be avoided, they may be removed in a future release. In all
of these cases, the context parameter acts as a freebie; it doesn't match
against a context value as it represents <em>all</em> context values.</p><h2
id="ComponentEvents-AccessingRequestQueryParameters">Accessing Request Query
Parameters</h2><p>A parameter may be annotated with the @RequestParameter
annotation; this allows a query parameter to be extracted from the request,
converted to the correct type, and passed to the method. Again, this doesn't
count against the event context values.</p><h2
id="ComponentEvents-MethodMatching">Method Matching</h2><p>An event handler
method will only be invoked <em>if the context contains at least as many values
as the method has parameters</em>. Methods with too many parameters will be
silently skipped.</p><p>Tapestry will silently skip over a method if there are
insuffi
cient values in the context to satisfy the number of parameters
requested.</p><p>EventContext parameters, and parameters annotated with
@RequestParameter, do not count against this limit.</p><h2
id="ComponentEvents-MethodOrdering">Method Ordering</h2><p>When multiple
methods match within the same class, Tapestry will invoke them in ascending
alphabetical order. When there are multiple overrides of the same method name,
Tapestry invokes them in descending order by number of parameters. In general,
these situations don't happen ... in most cases, only a single method is
required to handle a specific event form a specific component.</p><p>An event
handler method may return the value <code>true</code> to indicate that the
event has been handled; this immediately stops the search for additional
methods in the same class (or in base classes) or in containing
components.</p><h1 id="ComponentEvents-EventBubbling">Event Bubbling</h1><p>The
event will bubble up the hierarchy, until it is abor
ted. The event is aborted when an event handler method returns a non-null
value.</p><p>Returning a boolean value from an event handler method is special.
Returning true will abort the event with no result; use this when the event is
fully handled without a return value and no further event handlers (in the same
component, or in containing components) should be invoked.</p><p>Returning
false is the same as returning null; event processing will continue to look for
more event handlers, in the same component or its parent.</p><p>When an event
bubbles up from a component to its container, the origin of the event is
changed to be the component. For example, a Form component inside a
BeanEditForm component may fire a success event. The page containing the
BeanEditForm may listen for that event, but it will be from the BeanEditForm
component (which makes sense, because the id of the Form inside the
BeanEditForm is part of the BeanEditForm's implementation, not its public
interface).</p><h1
id="ComponentEvents-EventMethodExceptions">Event Method
Exceptions</h1><p>Event methods are allowed to throw any exception (not just
runtime exceptions). If an event method does throw an exception, Tapestry will
catch the thrown exception and ultimately display the exception report
page.</p><p>In other words, there's no need to do this:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><div class="confluence-information-macro
confluence-information-macro-information"><span class="aui-icon aui-icon-small
aui-iconfont-info confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>Note from Howard: I've found that
I prefer the naming convention approach, and reserve the annotation just for
situations that don't otherwise fit.</p></div></div><h2
id="ComponentEvents-MethodReturnValues">Method Return Values</h2><p>Main
Article: <a href="page-navigation.html">Page Navigation</a></p><p>For page
navigation events (originating in components such as EventLink, ActionLink and
Form), the value returned from an event handler method determines how Tapestry
will render a response.</p><ul><li><strong>Null</strong>: For no value, or
null, the current page (the page containing the component) will render the
response.</li><li><strong>Page</strong>: For the name of a page, or a page
class or page instance, a render request URL will be con
structed and sent to the client as a redirect to that
page.</li><li><strong>URL</strong>: For a java.net.URL, a redirect will be sent
to the client. (In Tapestry 5.3.x and earlier, this only works for non-Ajax
requests.)</li><li><strong>Zone body</strong>: In the case of an Ajax request
to update a zone, the component event handler will return the new zone body,
typically via an injected component or
block.</li><li><strong>HttpError</strong>: For an <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/HttpError.html">HttpError</a>,
an error response is sent to the client.</li><li><strong>Link</strong>: For a
<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Link.html">Link</a>,
a redirect is sent to the client.</li><li><strong>Stream</strong>: For a <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/StreamResponse.html">StreamResponse</a>,
a
stream of data is sent to the client</li><li><strong>boolean:</strong>
<em>true</em> prevents the event from bubbling up further; <em>false</em> lets
it bubble up. See Event Bubbling, below.</li></ul><p>See <a
href="page-navigation.html">Page Navigation</a> for more details.</p><h2
id="ComponentEvents-MultipleMethodMatches">Multiple Method Matches</h2><p>In
some cases, there may be multiple event handler methods matching a single
event. In that case, Tapestry invokes them in the following
order:</p><ul><li>Base class methods before sub-class methods.</li><li>Matching
methods within a class in alphabetical order.</li><li>For a single method name
with multiple overrides, by number of parameters, descending.</li></ul><p>Of
course, ordinarily would you <em>not</em> want to create more than one method
to handle an event.</p><p>When a sub-class overrides an event handler method of
a base class, the event handler method is only invoked once, along with any
other base class methods. The su
bclass can change the <em>implementation</em> of the base class method via an
override, but can't change the <em>timing</em> of when that method is invoked.
See <a class="external-link"
href="https://issues.apache.org/jira/browse/TAP5-51">issue TAP5-51</a>.</p><h2
id="ComponentEvents-EventContext">Event Context</h2><p>The context values (the
context parameter to the EventLink or ActionLink component) can be any object.
However, only a simple conversion to string occurs. (This is in contrast to
Tapestry 4, which had an elaborate type mechanism with the odd name
"DataSqueezer".)</p><p>Again, whatever your value is (string, number, date), it
is converted into a plain string. This results in a more readable URL.</p><p>If
you have multiple context values (by binding a list or array of objects to the
<em>context</em> parameter of the EventLink or ActionLink), then each one, in
order, will be added to the URL.</p><p>When an event handler method is invoked,
the strings are converted back i
nto values, or even objects. A <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ValueEncoder.html">ValueEncoder</a>
is used to convert between client-side strings and server-side objects. The <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ValueEncoderSource.html">ValueEncoderSource</a>
service provides the necessary value encoders.</p><p>As shown in the example
above, most of the parameters passed to the event handler method are derived
from the values provided in the event context. Each successive method parameter
matches against a value provided in the event context (the context parameter of
the ActionLink component; though many components have a similar context
parameter).</p><p>In some cases, it is desirable to have direct access to the
context (for example, to adapt to cases where there are a variable number of
context values). The context values may be passed to an event ha
ndler method as parameter of the following types:</p><ul><li><a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/EventContext.html">EventContext</a></li><li>Object[]</li><li>List<Object></li></ul><p>The
latter two should be avoided, they may be removed in a future release. In all
of these cases, the context parameter acts as a freebie; it doesn't match
against a context value as it represents <em>all</em> context values.</p><h2
id="ComponentEvents-AccessingRequestQueryParameters">Accessing Request Query
Parameters</h2><p>A parameter may be annotated with the @RequestParameter
annotation; this allows query parameters (?name1=value1&name2=value2, etc)
to be extracted from the request, converted to the correct type, and passed to
the method. Again, this doesn't count against the event context values.</p><h2
id="ComponentEvents-MethodMatching">Method Matching</h2><p>An event handler
method will only be invoked <em>if the context cont
ains at least as many values as the method has parameters</em>. Methods with
too many parameters will be silently skipped.</p><p>Tapestry will silently skip
over a method if there are insufficient values in the context to satisfy the
number of parameters requested.</p><p>EventContext parameters, and parameters
annotated with @RequestParameter, do not count against this limit.</p><h2
id="ComponentEvents-MethodOrdering">Method Ordering</h2><p>When multiple
methods match within the same class, Tapestry will invoke them in ascending
alphabetical order. When there are multiple overrides of the same method name,
Tapestry invokes them in descending order by number of parameters. In general,
these situations don't happen ... in most cases, only a single method is
required to handle a specific event form a specific component.</p><p>An event
handler method may return the value <code>true</code> to indicate that the
event has been handled; this immediately stops the search for additional metho
ds in the same class (or in base classes) or in containing components.</p><h1
id="ComponentEvents-EventBubbling">Event Bubbling</h1><p>The event will bubble
up the component hierarchy, first to the containing component, then
<em>that</em> component's containing component or page, and so on, until it is
<em>aborted</em> by an event handler method returning <em>true</em> or a
non-null value.</p><p>Returning a boolean value from an event handler method is
special. Returning <em>true</em> will abort the event with no result; use this
when the event is fully handled without a return value and no further event
handlers (in the same component, or in containing components) should be
invoked.</p><p>Returning <em>false</em> is the same as returning null; event
processing will continue to look for more event handlers, in the same component
or its parent.</p><p>When an event bubbles up from a component to its
container, the origin of the event is changed to be the component. For example,
a Form
component inside a BeanEditForm component may fire a success event. The page
containing the BeanEditForm may listen for that event, but it will be from the
BeanEditForm component (which makes sense, because the id of the Form inside
the BeanEditForm is part of the BeanEditForm's implementation, not its public
interface).</p><p>If you want to handle events that have bubbled up from nested
component, you'll soon find that you don't have easy access to the component ID
of the firing component. In practical terms this means that you'll want to
trigger custom events for the events emitted by those nested components (see
Triggering Events, below), and use that custom event name in your event handler
method.</p><h1 id="ComponentEvents-EventMethodExceptions">Event Method
Exceptions</h1><p>Event methods are allowed to throw any exception (not just
runtime exceptions). If an event method does throw an exception, Tapestry will
catch the thrown exception and ultimately display the exception re
port page.</p><p>In other words, there's no need to do this:</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;"> void onActionFromRunQuery()
{
try
@@ -198,7 +202,19 @@
return this;
}
</pre>
-</div></div><p>The return value of the exception event handler
<em>replaces</em> the return value of original event handler method. For the
typical case (an exception thrown by an "activate" or "action" event), this
will be a <a href="page-navigation.html">navigational response</a> such as a
page instance or page name.</p><p>This can be handy for handling cases where
the data in the URL is incorrectly formatted.</p><p>In the above example, the
navigational response is the page itself.</p><p>If there is no exception event
handler, or the exception event handler returns null (or is void), then the
exception will be passed to the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/RequestExceptionHandler.html">RequestExceptionHandler</a>
service, which (in the default configuration) will render the exception
page.</p></div>
+</div></div><p>The return value of the exception event handler
<em>replaces</em> the return value of original event handler method. For the
typical case (an exception thrown by an "activate" or "action" event), this
will be a <a href="page-navigation.html">navigational response</a> such as a
page instance or page name.</p><p>This can be handy for handling cases where
the data in the URL is incorrectly formatted.</p><p>In the above example, the
navigational response is the page itself.</p><p>If there is no exception event
handler, or the exception event handler returns null (or is void), then the
exception will be passed to the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/RequestExceptionHandler.html">RequestExceptionHandler</a>
service, which (in the default configuration) will render the exception
page.</p><h1 id="ComponentEvents-TriggeringEvents">Triggering Events</h1><p>If
you want your own component to trigger events,
just call the <a rel="nofollow">triggerEvent</a> method of <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ComponentResources.html">ComponentResources</a>
from within the component class.</p><p>For example, the following emits an
"updateAll" event. A containing component can then respond to it, if desired,
with an "onUpdateAll()" method in its own component class.</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl"
style="border-bottom-width: 1px;"><b>Your component class
(partial)</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">@Inject
+ComponentResources componentResources;
+ ...
+private void timeToUpdate() {
+ boolean wasHandled = componentResources.triggerEvent("updateAll", null,
null);
+ if (wasHandled) {
+ ...
+ }
+} </pre>
+</div></div><p>The third parameter to triggerEvent is a
ComponentEventCallback, which you'll only need to implement if you want to get
the return value of the handler method. The return value of <span
class="il">triggerEvent</span>() says if the <span class="il">event</span> was
handled or not.</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/together/ajaxcomponentscrud/persons"
rel="nofollow">AJAX Components CRUD</a></p></div></div>
</div>
<div class="clearer"></div>