Author: buildbot
Date: Sun Feb 18 17:21:12 2018
New Revision: 1025563
Log:
Production update by buildbot for tapestry
Modified:
websites/production/tapestry/content/assets.html
websites/production/tapestry/content/beaneditform-guide.html
websites/production/tapestry/content/cache/main.pageCache
websites/production/tapestry/content/css.html
websites/production/tapestry/content/environmental-services.html
websites/production/tapestry/content/forms-and-validation.html
websites/production/tapestry/content/injection.html
websites/production/tapestry/content/logging.html
websites/production/tapestry/content/uploading-files.html
Modified: websites/production/tapestry/content/assets.html
==============================================================================
--- websites/production/tapestry/content/assets.html (original)
+++ websites/production/tapestry/content/assets.html Sun Feb 18 17:21:12 2018
@@ -184,7 +184,7 @@ private Asset style;
<version>5.4</version>
</dependency>
</pre>
-</div></div></div></div></div></div><p> </p><p>By adding this dependency,
all your JavaScript and CSS files will be minimized when <a
href="configuration.html">PRODUCTION_MODE=true</a>. You can force the
minimization of these files, by changing the value of the constant
SymbolConstants.MINIFICATION_ENABLED in your module class (usually
AppModule.java):</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>AppModule.java (partial)</b></div><div class="codeContent panelContent
pdl">
+</div></div></div></div></div></div><p> </p><p>By adding this dependency,
all your JavaScript and CSS files will be minimized when <a
href="configuration.html">Production Mode</a> is true. You can force the
minimization of these files, by changing the value of the constant
SymbolConstants.MINIFICATION_ENABLED in your module class (usually
AppModule.java):</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>AppModule.java (partial)</b></div><div class="codeContent panelContent
pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">@Contribute(SymbolProvider.class)
@ApplicationDefaults
public static void
contributeApplicationDefaults(MappedConfiguration<String, String>
configuration)
Modified: websites/production/tapestry/content/beaneditform-guide.html
==============================================================================
--- websites/production/tapestry/content/beaneditform-guide.html (original)
+++ websites/production/tapestry/content/beaneditform-guide.html Sun Feb 18
17:21:12 2018
@@ -81,7 +81,7 @@
<p> <strong>JumpStart Demos:</strong><br clear="none">
<a class="external-link"
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/input/edit1/1"
rel="nofollow">Edit (Using BeanEditForm)</a><br clear="none">
<a class="external-link"
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/input/create1"
rel="nofollow">Create (Using BeanEditForm)</a><br clear="none">
- <a class="external-link"
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/input/morecontroledit1/1"
rel="nofollow">More Control Edit (Using BeanEditor)</a></p></div>BeanEditForm
analyzes the the properties of the bean, locating just those properties that
are readable and writeable. It filters down to properties whose type is mapped
to a known editor (this is described in more detail below).<p>The default
ordering for properties is in the order in which the <em>getter methods</em>
for the properties are defined. When a super-class defines editable properties,
those are ordered before sub-class properties.</p><h2
id="BeanEditFormGuide-SupportedTypes">Supported Types</h2><p>The default set of
property types supported by BeanEditForm:</p><ul><li>String: as a text
field</li><li>Number: as a text field</li><li>Enum: as a drop-down
list</li><li>Boolean: as a checkbox</li><li>Date: as a JavaScript
calendar</li><li>Calendar: as a JavaScript calendar</li></ul><p>Resolving
a property type to an editor type involves a search up the inheritance
hierarchy: thus the super-type of Integer, Long, BigDecimal, etc. is Number,
which uses a text field for data entry.</p><p>The list of supported property
types is extensible (this is documented below).</p><h2
id="BeanEditFormGuide-AutomaticObjectCreation">Automatic Object
Creation</h2><p>When a page is rendered, the BeanEditForm component will read
its object parameter as the JavaBean to edit (with the current properties of
the JavaBean becoming the defaults for the various fields). Likewise, when the
form is submitted by the user, the object parameter is read and its properties
populated from the request.</p><p>If the object does not exist, it will be
created as needed. The type is determined from the property type, which should
be a specific type in order for automatic creation to operate
properly.</p><p>The BeanEditForm component will attempt to instantiate a value
for the property as necessary, when the form
is submitted. This can be a problem when the property type is an interface,
rather than an instantiable class.</p><p>One option is to provide an event
handler for the "prepare" or "prepareForSubmit" events to instantiate an
instance to receive the submitted information.</p><p>For a class, Tapestry will
select the public constructor with the <em>most</em> parameters. If this is not
desirable (for example, if you get an exception), then place the @<a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html">Inject</a>
annotation on the constructor Tapestry should use.</p><h2
id="BeanEditFormGuide-ImplicitObjectBinding">Implicit Object Binding</h2><p>If
the object parameter is not bound, then an implicit binding to a property of
the containing component is made. The bound property will be the BeanEditForm
component's id, if such a property exists. Thus you may typically give the
BeanEditForm component an id (that matches a
property) and not have to bind the object parameter.</p><h2
id="BeanEditFormGuide-Non-VisualProperties">Non-Visual Properties</h2><p>In
some cases, a property may be updatable and of a supported type for editing,
but should not be presented to the user for editing: for example, a property
that holds the primary key of a database entity. In such a case, the @<a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/beaneditor/NonVisual.html">NonVisual</a>
annotation may be applied to the property (either the getter or the setter
method).</p><h2 id="BeanEditFormGuide-DefaultValidation">Default
Validation</h2><p>Default validation for fields is primary determined by
property type.</p><p>If desired, additional validation may be specified using
the @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/beaneditor/Validate.html">Validate</a>
annotation. See <a href="beaneditform-guide.html">BeanEditForm Guid
e</a>.</p><p>As of Tapestry 5.2, validation may also be specified via the
containing component's property file, using a key in the form of
<code>propertyId-validate</code> (eg: myfield-validate=required).</p><h2
id="BeanEditFormGuide-Propertyordering">Property ordering</h2><p>By default,
the order in which properties are presented is as defined above (order of the
getter method). This can be overridden using the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/beaneditor/ReorderProperties.html">ReorderProperties</a>
class annotation.</p><h2 id="BeanEditFormGuide-DefaultLabel">Default
Label</h2><p>Tapestry will attempt to provide a reasonable default label for
each field, based on the property name being emitted. The property name is
capitalized, and spaces are added before case changes, thus property "name"
becomes label "Name" and property "streetAddress" becomes label "Street
Address".</p><p>BeanEditForm also searches for a label for
the field in the containing component's message catalog. The message key is
the property name suffixed with "-label". If such a label is found, it takes
precedence.</p><h1 id="BeanEditFormGuide-PropertyEditorOverrides">Property
Editor Overrides</h1><p>You may override the editor for any particular
property, using the a block parameter to the BeanEditForm component.</p><p>An
editor normally consists of a Label component and some form of field component
(such as TextField or TextArea).</p><p>For example, you may want to selectively
use a PasswordField component:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+ <a class="external-link"
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/input/morecontroledit1/1"
rel="nofollow">More Control Edit (Using BeanEditor)</a></p></div>BeanEditForm
analyzes the the properties of the bean, locating just those properties that
are readable and writeable. It filters down to properties whose type is mapped
to a known editor (this is described in more detail below).<p>The default
ordering for properties is in the order in which the <em>getter methods</em>
for the properties are defined. When a super-class defines editable properties,
those are ordered before sub-class properties.</p><h2
id="BeanEditFormGuide-SupportedTypes">Supported Types</h2><p>The default set of
property types supported by BeanEditForm:</p><ul><li>String: as a text
field</li><li>Number: as a text field</li><li>Enum: as a drop-down
list</li><li>Boolean: as a checkbox</li><li>Date: as a JavaScript
calendar</li><li>Calendar: as a JavaScript calendar</li></ul><p>Resolving
a property type to an editor type involves a search up the inheritance
hierarchy: thus the super-type of Integer, Long, BigDecimal, etc. is Number,
which uses a text field for data entry.</p><p>The list of supported property
types is extensible (this is documented below).</p><h2
id="BeanEditFormGuide-AutomaticObjectCreation">Automatic Object
Creation</h2><p>When a page is rendered, the BeanEditForm component will read
its object parameter as the JavaBean to edit (with the current properties of
the JavaBean becoming the defaults for the various fields). Likewise, when the
form is submitted by the user, the object parameter is read and its properties
populated from the request.</p><p>If the object does not exist, it will be
created as needed. The type is determined from the property type, which should
be a specific type in order for automatic creation to operate
properly.</p><p>The BeanEditForm component will attempt to instantiate a value
for the property as necessary, when the form
is submitted. This can be a problem when the property type is an interface,
rather than an instantiable class.</p><p>One option is to provide an event
handler for the "prepare" or "prepareForSubmit" events to instantiate an
instance to receive the submitted information.</p><p>For a class, Tapestry will
select the public constructor with the <em>most</em> parameters. If this is not
desirable (for example, if you get an exception), then place the @<a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html">Inject</a>
annotation on the constructor Tapestry should use.</p><h2
id="BeanEditFormGuide-ImplicitObjectBinding">Implicit Object Binding</h2><p>If
the object parameter is not bound, then an implicit binding to a property of
the containing component is made. The bound property will be the BeanEditForm
component's id, if such a property exists. Thus you may typically give the
BeanEditForm component an id (that matches a
property) and not have to bind the object parameter.</p><h2
id="BeanEditFormGuide-Non-VisualProperties">Non-Visual Properties</h2><p>In
some cases, a property may be updatable and of a supported type for editing,
but should not be presented to the user for editing: for example, a property
that holds the primary key of a database entity. In such a case, the @<a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/beaneditor/NonVisual.html">NonVisual</a>
annotation may be applied to the property (either the getter or the setter
method).</p><h2 id="BeanEditFormGuide-DefaultValidation">Default
Validation</h2><p>Default validation for fields is primary determined by
property type.</p><p>If desired, additional validation may be specified using
the @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/beaneditor/Validate.html">Validate</a>
annotation. See <a href="forms-and-validation.html">Forms and Valid
ation</a>.</p><p>As of Tapestry 5.2, validation may also be specified via the
containing component's property file, using a key in the form of
<code>propertyId-validate</code> (eg: myfield-validate=required).</p><h2
id="BeanEditFormGuide-Propertyordering">Property ordering</h2><p>By default,
the order in which properties are presented is as defined above (order of the
getter method). This can be overridden using the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/beaneditor/ReorderProperties.html">ReorderProperties</a>
class annotation.</p><h2 id="BeanEditFormGuide-DefaultLabel">Default
Label</h2><p>Tapestry will attempt to provide a reasonable default label for
each field, based on the property name being emitted. The property name is
capitalized, and spaces are added before case changes, thus property "name"
becomes label "Name" and property "streetAddress" becomes label "Street
Address".</p><p>BeanEditForm also searches for a label
for the field in the containing component's message catalog. The message key
is the property name suffixed with "-label". If such a label is found, it takes
precedence.</p><h1 id="BeanEditFormGuide-PropertyEditorOverrides">Property
Editor Overrides</h1><p>You may override the editor for any particular
property, using the a block parameter to the BeanEditForm component.</p><p>An
editor normally consists of a Label component and some form of field component
(such as TextField or TextArea).</p><p>For example, you may want to selectively
use a PasswordField component:</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:beaneditform object="loginCredentials">
<p:password>
<t:label for="password"/>
Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.
Modified: websites/production/tapestry/content/css.html
==============================================================================
--- websites/production/tapestry/content/css.html (original)
+++ websites/production/tapestry/content/css.html Sun Feb 18 17:21:12 2018
@@ -76,7 +76,7 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><p>Most web applications delegate
to <strong>Cascading Style Sheets</strong> (CSS) the stylistic details of the
page – fonts, colors, margins, borders and alignment. This helps the
remaining HTML to remain simple and semantic, which usually makes it easier to
read and maintain.</p><div class="aui-label" style="float:right" title="Related
Articles">
+ <div id="ConfluenceContent"><p> </p><p>Most web
applications delegate to <strong>Cascading Style Sheets</strong> (CSS) the
stylistic details of the page – fonts, colors, margins, borders and
alignment. This helps the remaining HTML to remain simple and semantic, which
usually makes it easier to read and maintain.</p><div class="aui-label"
style="float:right" title="Related Articles">
@@ -127,24 +127,24 @@
</div>
-<p>Tapestry includes sophisticated support for CSS in the form of
annotation-based linking, far-future expire headers, automatic duplicate
removal, and other features provided for <a href="css.html">assets</a>.</p><h2
id="CSS-Defaultstylesheet">Default style sheet</h2><p>Tapestry includes a
built-in style sheet, tapestry.css, in all HTML documents (documents that have
an outer <html> element and a nested <head> element), as part of
the "core" JavaScript stack. For Tapestry 5.4 and later, the core JavaScript
stack also includes the CSS for <a class="external-link"
href="http://getbootstrap.com/" rel="nofollow">Bootstrap 3.1.1</a>.</p><h2
id="CSS-AddingyourownCSS">Adding your own CSS</h2><p>A page or component (for
example, a <a href="css.html">layout component</a>) that is rendering the
<head> tag can add a style sheet directly in the markup.</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;"><head>
+<p>Tapestry includes sophisticated support for CSS in the form of
annotation-based linking, far-future expire headers, automatic duplicate
removal, and other features provided for <a
href="assets.html">assets</a>.</p><h2 id="CSS-Defaultstylesheet">Default style
sheet</h2><p>Tapestry includes a built-in style sheet, tapestry.css, in all
HTML documents (documents that have an outer <html> element and a nested
<head> element), as part of the "core" JavaScript stack. For Tapestry 5.4
and later, the core JavaScript stack also includes the CSS for <a
class="external-link" href="http://getbootstrap.com/" rel="nofollow">Bootstrap
3.1.1</a>.</p><h2 id="CSS-AddingyourownCSS">Adding your own CSS</h2><p>A page
or component (for example, a <a href="layout-component.html">layout
component</a>) that is rendering the <head> tag can add a style sheet
directly in the 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;"><head>
<link href="/css/site.css" rel="stylesheet" type="text/css"/>
. . .
</pre>
</div></div><p>If you want to leverage Tapestry's localization support, you
may want to make use of an expansion and the "asset:" or "context:" binding
prefix:</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;"><head>
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><head>
<link href="${context:css/site.css}" rel="stylesheet" type="text/css"/>
. . .
</pre>
-</div></div><p>The "context:" prefix means that the remainder of the expansion
is a path to a context asset, a resource in the web application root
(<code>src/main/webapp</code> in your workspace). By contrast, the "asset:"
prefix tells Tapestry to look in the class path. See <a
href="css.html">CSS</a>.</p><h2 id="CSS-Usingthe@Importannotation">Using the
@Import annotation</h2><p>Another approach to adding a style sheet is to
include an @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Import.html">Import</a>
annotation (starting with Tapestry 5.2) on your component class:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+</div></div><p>The "context:" prefix means that the remainder of the expansion
is a path to a context asset, a resource in the web application root
(<code>src/main/webapp</code> in your workspace). By contrast, the "asset:"
prefix tells Tapestry to look in the class path. See <a
href="assets.html">CSS</a>.</p><h2 id="CSS-Usingthe@Importannotation">Using the
@Import annotation</h2><p>Another approach to adding a style sheet is to
include an @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Import.html">Import</a>
annotation (starting with Tapestry 5.2) on your component class:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader
panelHeader pdl" style="border-bottom-width:
1px;"><b>MyComponent.java</b></div><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">@Import(stylesheet="context:css/site.css")
public class MyComponent
{
}
</pre>
-</div></div><p>(For Tapestry 5.0 and 5.1, use the deprecated <a
class="external-link"
href="http://tapestry.apache.org/5.2/apidocs/org/apache/tapestry5/annotations/IncludeStylesheet.html">@IncludeStyleSheet</a>
annotation instead.)</p><p>As with <a href="css.html">included JavaScript
libraries</a>, each style sheet will only be added once, regardless of the
number of components that include it via the annotation.</p><h2
id="CSS-ConditionallyloadingIE-onlystylesheets">Conditionally loading IE-only
style sheets</h2><p>For Tapestry 5.2 and later, if you need to load a different
style sheet for Internet Explorer browsers, or for certain versions of IE
browsers, you can use Tapestry's built-in support for IE conditional comments.
Just add something like the following to your page or component (or layout)
class:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+</div></div><p>(For Tapestry 5.0 and 5.1, use the deprecated <a
class="external-link"
href="http://tapestry.apache.org/5.2/apidocs/org/apache/tapestry5/annotations/IncludeStylesheet.html">@IncludeStyleSheet</a>
annotation instead.)</p><p>As with <a
href="client-side-javascript.html">included JavaScript libraries</a>, each
style sheet will only be added once, regardless of the number of components
that include it via the annotation.</p><h2
id="CSS-ConditionallyloadingIE-onlystylesheets">Conditionally loading IE-only
style sheets</h2><p>For Tapestry 5.2 and later, if you need to load a different
style sheet for Internet Explorer browsers, or for certain versions of IE
browsers, you can use Tapestry's built-in support for IE conditional comments.
Just add something like the following to your page or component (or layout)
class:</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;">@Environmental
private JavaScriptSupport javaScriptSupport;
Modified: websites/production/tapestry/content/environmental-services.html
==============================================================================
--- websites/production/tapestry/content/environmental-services.html (original)
+++ websites/production/tapestry/content/environmental-services.html Sun Feb 18
17:21:12 2018
@@ -80,7 +80,7 @@
<div id="ConfluenceContent"><div class="navmenu"
style="float:right; width:30%; background:#eee; margin:3px; padding:3px">
<p>Environmental services represent yet another, distinct form of
injection.</p>
-<p>Unlike service injection (injection via a service implementation's
constructor) or normal component injection (directly into component fields, via
the @Inject annotation) where the injected value is always the same, with
environmental services, the injected value is very late bound and
dynamic.</p></div><strong>Environmental services</strong> provide a conduit of
communication between two components (usually a component and the components it
encloses). The first component pushes an object of a certain type into the
<em>environment</em>, and then the second component can access that object
merely by defining an annotated property of the same type.<p>An example of how
this works is Tapestry's built-in <em>form support</em>. The <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Form.html">Form</a>
component creates an object of type <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/t
apestry5/services/FormSupport.html">FormSupport</a> and pushes it into the
environment. Then, the enclosed form components can use that FormSupport object
to participate in both the rendering of the Form and the Form's eventual
submission. This is how control names and client-side ids are determined, how
fields register callbacks so that they can process their part of the
submission, and how fields hook themselves to client-side validation.</p><h1
id="EnvironmentalServices-Usingthe@Environmentalannotation">Using the
@Environmental annotation</h1><p>The @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Environmental.html">Environmental</a>
annotation, when used in a component class, causes the associated field to be
replaced at runtime with a read-only value obtained from an Environment service
provided by an enclosing component.</p><p>A very common Environmental is <a
class="external-link" href="http://tapestry.apache.org/c
urrent/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html">JavaScriptSupport</a>,
used when generating <a href="environmental-services.html">client-side
JavaScript</a>.</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+<p>Unlike service injection (injection via a service implementation's
constructor) or normal component injection (directly into component fields, via
the @Inject annotation) where the injected value is always the same, with
environmental services, the injected value is very late bound and
dynamic.</p></div><strong>Environmental services</strong> provide a conduit of
communication between two components (usually a component and the components it
encloses). The first component pushes an object of a certain type into the
<em>environment</em>, and then the second component can access that object
merely by defining an annotated property of the same type.<p>An example of how
this works is Tapestry's built-in <em>form support</em>. The <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Form.html">Form</a>
component creates an object of type <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/t
apestry5/services/FormSupport.html">FormSupport</a> and pushes it into the
environment. Then, the enclosed form components can use that FormSupport object
to participate in both the rendering of the Form and the Form's eventual
submission. This is how control names and client-side ids are determined, how
fields register callbacks so that they can process their part of the
submission, and how fields hook themselves to client-side validation.</p><h1
id="EnvironmentalServices-Usingthe@Environmentalannotation">Using the
@Environmental annotation</h1><p>The @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Environmental.html">Environmental</a>
annotation, when used in a component class, causes the associated field to be
replaced at runtime with a read-only value obtained from an Environment service
provided by an enclosing component.</p><p>A very common Environmental is <a
class="external-link" href="http://tapestry.apache.org/c
urrent/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html">JavaScriptSupport</a>,
used when generating <a href="ajax-javascript.html">client-side
JavaScript</a>.</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 @Path("${tapestry.scriptaculous}/dragdrop.js")
private Asset dragDropLibrary;
@@ -93,7 +93,7 @@
}
</pre>
-</div></div><p>Environmental services are, by their nature, per-thread (and
therefore per-request).</p><p>Accessing an environmental field causes a lookup,
by type, against the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/Environment.html">Environment</a>
service.</p><p>Normally, an environmental of the specified type must be
available in the Environment, or an exception is thrown when accessing the
field. However, if the value of the Environmental annotation's value is false,
then the environmental value is optional.</p><h1
id="EnvironmentalServices-Placingavalueintheenvironment">Placing a value in the
environment</h1><p>The Environment service has push() and pop() methods to put
a value in the Environment, and discard it.</p><p>For example, say you were
building a tab-based menu system and you needed to allow an outer TabGroup
component to communicate with inner Tab components, to control various aspects
of presentation.<
/p><p>The relevant information could be exposed as an interface,
TabModel.</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+</div></div><p>Environmental services are, by their nature, per-thread (and
therefore per-request).</p><p>Accessing an environmental field causes a lookup,
by type, against the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/Environment.html">Environment</a>
service.</p><p>Normally, an environmental of the specified type must be
available in the Environment, or an exception is thrown when accessing the
field. However, if the value of the Environmental annotation's value is false,
then the environmental value is optional.</p><h1
id="EnvironmentalServices-Placingavalueintheenvironment">Placing a value in the
environment</h1><p>The Environment service has push() and pop() methods to put
a value in the Environment, and discard it.</p><p>For example, say you were
building a tab-based menu system and you needed to allow an outer TabGroup
component to communicate with inner Tab components, to control various aspects
of presentation.<
/p><p>The relevant information could be exposed as an interface,
TabModel.</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>TabGroup.java</b></div><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">public class TabGroup
{
@Inject
Modified: websites/production/tapestry/content/forms-and-validation.html
==============================================================================
--- websites/production/tapestry/content/forms-and-validation.html (original)
+++ websites/production/tapestry/content/forms-and-validation.html Sun Feb 18
17:21:12 2018
@@ -77,7 +77,7 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><p><strong>Forms</strong> are the
traditional way for most web applications to gather significant information
from the user. Whether it's a search form, a login screen or a multi-page
registration wizard, Tapestry uses standard HTML forms, with HTTP POST actions
by default. In addition, AJAX-based form submission is supported using <a
href="forms-and-validation.html">Zones</a>.</p><div class="aui-label"
style="float:right" title="Related Articles">
+ <div id="ConfluenceContent"><p><strong>Forms</strong> are the
traditional way for most web applications to gather significant information
from the user. Whether it's a search form, a login screen or a multi-page
registration wizard, Tapestry uses standard HTML forms, with HTTP POST actions
by default. In addition, AJAX-based form submission is supported using <a
href="ajax-and-zones.html">Zones</a>.</p><div class="aui-label"
style="float:right" title="Related Articles">
@@ -120,11 +120,11 @@
<p> </p><p>Tapestry provides support for creating and rendering forms,
populating their fields, and validating user input. For simple cases, input
validation is declarative, meaning you simply tell Tapestry what validations to
apply to a given field, and it takes care of it on the server and (optionally)
on the client as well. In addition, you can provide event handler
methods in your page or component classes to handle more complex
validation scenarios.</p><p>Finally, Tapestry not only makes it easy to present
errors messages to the user, but it can also automatically highlight form
fields when validation fails.</p><p><strong>Contents</strong></p><p><style
type="text/css">/*<![CDATA[*/
-div.rbtoc1518909566916 {padding: 0px;}
-div.rbtoc1518909566916 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1518909566916 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1518974453974 {padding: 0px;}
+div.rbtoc1518974453974 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1518974453974 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1518909566916">
+/*]]>*/</style></p><div class="toc-macro rbtoc1518974453974">
<ul class="toc-indentation"><li>Related Articles</li></ul>
<ul><li><a href="#FormsandValidation-TheFormComponent">The Form Component</a>
<ul class="toc-indentation"><li><a href="#FormsandValidation-FormEvents">Form
Events</a></li><li><a href="#FormsandValidation-HandlingEvents">Handling
Events</a></li><li><a
href="#FormsandValidation-TrackingValidationErrors">Tracking Validation
Errors</a></li><li><a
href="#FormsandValidation-StoringDataBetweenRequests">Storing Data Between
Requests</a></li><li><a
href="#FormsandValidation-ConfiguringFieldsandLabels">Configuring Fields and
Labels</a></li></ul>
@@ -132,15 +132,15 @@ div.rbtoc1518909566916 li {margin-left:
<ul class="toc-indentation"><li><a
href="#FormsandValidation-AvailableValidators">Available
Validators</a></li><li><a
href="#FormsandValidation-CentralizingValidationwith@Validate">Centralizing
Validation with @Validate</a></li><li><a
href="#FormsandValidation-HTML5Client-sideValidation">HTML5 Client-side
Validation</a></li><li><a
href="#FormsandValidation-ServerSideValidation">Server Side
Validation</a></li><li><a
href="#FormsandValidation-CustomizingValidationMessages">Customizing Validation
Messages</a>
<ul class="toc-indentation"><li><a
href="#FormsandValidation-CustomizingValidationMessagesforBeanEditForm">Customizing
Validation Messages for BeanEditForm</a></li></ul>
</li><li><a
href="#FormsandValidation-ConfiguringValidatorContraintsintheMessageCatalog">Configuring
Validator Contraints in the Message Catalog</a></li><li><a
href="#FormsandValidation-ValidationMacros">Validation Macros</a></li><li><a
href="#FormsandValidation-OverridingtheTranslatorwithEvents">Overriding the
Translator with Events</a></li></ul>
-</li></ul></div><h1 id="FormsandValidation-TheFormComponent">The Form
Component</h1><p>The core of Tapestry's form support is the <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Form.html">Form</a>
component. The Form component encloses (wraps around) all the other <em>field
components</em> such as <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/TextField.html">TextField</a>,
<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/TextArea.html">TextArea</a>,
<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Checkbox.html">Checkbox</a>,
etc.</p><h2 id="FormsandValidation-FormEvents">Form Events</h2><p>The Form
component emits a number of <a href="forms-and-validation.html">component
events</a>. You'll want to provide event handl
er methods for some of these.</p><p>When rendering, the Form component emits
two events: first, "prepareForRender", then "prepare". These allow the Form's
container to set up any fields or properties that will be referenced in the
form. For example, this is a good place to create a temporary entity object to
be rendered, or to load an entity from a database to be edited.</p><p>When user
submits the form on the client, a series of steps occur on the
server.</p><p>First, the Form emits a "prepareForSubmit" event, then a
"prepare" event. These allow the container to ensure that objects are set up
and ready to receive information from the form submission.</p><p>Next, all the
fields inside the form are <em>activated</em> to pull values out of the
incoming request, validate them and (if valid) store the changes.</p><div
class="navmenu" style="float:right; width:25%; background:#eee; margin:3px;
padding:3px">
-<p><em>For Tapestry 4 Users:</em> Tapestry 5 does not use the fragile "form
rewind" approach from Tapestry 4. Instead, a hidden field generated during the
render stores the information needed to process the form
submission.</p></div> <p>After the fields have done their processing, the
Form emits a "validate" event. This is your chance to perform any cross-form
validation that can't be described declaratively.</p><p>Next, the Form
determines if there have been any validation errors. If there have been, then
the submission is considered a failure, and a "failure" event is emitted. If
there have been no validation errors, then a "success" event is
emitted.</p><p>Finally, the Form emits a "submit" event, for logic that doesn't
care about success or failure.</p><div class="table-wrap"><table
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1"
class="confluenceTh"><p>Form Event (in order)</p></th><th colspan="1"
rowspan="1" class="confluenceTh"><p>Phase</p></th><th colspan
="1" rowspan="1" class="confluenceTh"><p>When emitted (and typical
use)</p></th><th colspan="1" rowspan="1" class="confluenceTh">Method
Name</th><th colspan="1" rowspan="1" class="confluenceTh">@OnEvent
Constant</th></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><strong>prepareForRender</strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>Render</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Before rendering the form (e.g. load an
entity from a database to be edited)</p></td><td colspan="1" rowspan="1"
class="confluenceTd">onPrepareForRender()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.PREPARE_FOR_RENDER</td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p><strong>prepare</strong></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Render</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>Before rendering the form, but after
<em>prepareForRender</em></p></td><td colspan="1" rowspan="1" c
lass="confluenceTd">onPrepare()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.PREPARE</td></tr><tr><td colspan="1"
rowspan="1"
class="confluenceTd"><p><strong>prepareForSubmit</strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Before the submitted form is
processed</p></td><td colspan="1" rowspan="1"
class="confluenceTd">onPrepareForSubmit()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.PREPARE_FOR_SUBMIT</td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p><strong>prepare</strong></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>Before the submitted form is processed, but after
<em>prepareForSubmit</em></p></td><td colspan="1" rowspan="1"
class="confluenceTd">onPrepare()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.PREPARE</td></tr><tr><td cols
pan="1" rowspan="1"
class="confluenceTd"><p><strong>validate</strong></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>After fields have been populated from submitted values
and validated (e.g. perform cross-field validation)</p></td><td colspan="1"
rowspan="1" class="confluenceTd">onValidate</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.VALIDATE</td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong>validateForm</strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>same as <em>validate (deprecated – do
not use)<br clear="none"></em></p></td><td colspan="1" rowspan="1"
class="confluenceTd"><em>onValidateForm</em></td><td colspan="1" rowspan="1"
class="confluenceTd"> </td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><strong>failure</strong></p></td><td colspan=
"1" rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>After one or more validation errors have
occurred</p></td><td colspan="1" rowspan="1"
class="confluenceTd">onFailure()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.FAILURE</td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong>success</strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>When validation has completed
<em>without</em> any errors (e.g. save changes to the database)</p></td><td
colspan="1" rowspan="1" class="confluenceTd">onSuccess()</td><td colspan="1"
rowspan="1" class="confluenceTd">EventConstants.SUCCESS</td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p><strong>submit</strong></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>After all validation (s
uccess or failure) has finished</p></td><td colspan="1" rowspan="1"
class="confluenceTd">onSubmit()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.SUBMIT</td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><strong>canceled</strong></td><td colspan="1"
rowspan="1" class="confluenceTd">Submit</td><td colspan="1" rowspan="1"
class="confluenceTd">Whenever a <em>Submit</em> or <em>LinkSubmit</em>
component containing <em>mode="cancel"</em> or <em>mode="unconditional"</em> is
clicked</td><td colspan="1" rowspan="1"
class="confluenceTd">onCanceled()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.CANCELED</td></tr></tbody></table></div><p>Note
that the "prepare" event is emitted during both form rendering and form
submission.</p><h2 id="FormsandValidation-HandlingEvents">Handling
Events</h2><p>Main Article: <a href="forms-and-validation.html">Forms and
Validation</a></p><p>You handle events by providing methods in your page or
component c
lass, either following the
on<strong><em>Event</em></strong>From<strong><em>Component</em></strong>()
naming convention or using the OnEvent annotation. For example:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader
panelHeader pdl" style="border-bottom-width: 1px;"><b>Event Handler Using
Naming Convention</b></div><div class="codeContent panelContent pdl">
+</li></ul></div><h1 id="FormsandValidation-TheFormComponent">The Form
Component</h1><p>The core of Tapestry's form support is the <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Form.html">Form</a>
component. The Form component encloses (wraps around) all the other <em>field
components</em> such as <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/TextField.html">TextField</a>,
<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/TextArea.html">TextArea</a>,
<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Checkbox.html">Checkbox</a>,
etc.</p><h2 id="FormsandValidation-FormEvents">Form Events</h2><p>The Form
component emits a number of <a href="component-events.html">component
events</a>. You'll want to provide event handler m
ethods for some of these.</p><p>When rendering, the Form component emits two
events: first, "prepareForRender", then "prepare". These allow the Form's
container to set up any fields or properties that will be referenced in the
form. For example, this is a good place to create a temporary entity object to
be rendered, or to load an entity from a database to be edited.</p><p>When user
submits the form on the client, a series of steps occur on the
server.</p><p>First, the Form emits a "prepareForSubmit" event, then a
"prepare" event. These allow the container to ensure that objects are set up
and ready to receive information from the form submission.</p><p>Next, all the
fields inside the form are <em>activated</em> to pull values out of the
incoming request, validate them and (if valid) store the changes.</p><div
class="navmenu" style="float:right; width:25%; background:#eee; margin:3px;
padding:3px">
+<p><em>For Tapestry 4 Users:</em> Tapestry 5 does not use the fragile "form
rewind" approach from Tapestry 4. Instead, a hidden field generated during the
render stores the information needed to process the form
submission.</p></div> <p>After the fields have done their processing, the
Form emits a "validate" event. This is your chance to perform any cross-form
validation that can't be described declaratively.</p><p>Next, the Form
determines if there have been any validation errors. If there have been, then
the submission is considered a failure, and a "failure" event is emitted. If
there have been no validation errors, then a "success" event is
emitted.</p><p>Finally, the Form emits a "submit" event, for logic that doesn't
care about success or failure.</p><div class="table-wrap"><table
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1"
class="confluenceTh"><p>Form Event (in order)</p></th><th colspan="1"
rowspan="1" class="confluenceTh"><p>Phase</p></th><th colspan
="1" rowspan="1" class="confluenceTh"><p>When emitted (and typical
use)</p></th><th colspan="1" rowspan="1" class="confluenceTh">Method
Name</th><th colspan="1" rowspan="1" class="confluenceTh">@OnEvent
Constant</th></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><strong>prepareForRender</strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>Render</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Before rendering the form (e.g. load an
entity from a database to be edited)</p></td><td colspan="1" rowspan="1"
class="confluenceTd">onPrepareForRender()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.PREPARE_FOR_RENDER</td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p><strong>prepare</strong></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Render</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>Before rendering the form, but after
<em>prepareForRender</em></p></td><td colspan="1" rowspan="1" c
lass="confluenceTd">onPrepare()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.PREPARE</td></tr><tr><td colspan="1"
rowspan="1"
class="confluenceTd"><p><strong>prepareForSubmit</strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Before the submitted form is
processed</p></td><td colspan="1" rowspan="1"
class="confluenceTd">onPrepareForSubmit()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.PREPARE_FOR_SUBMIT</td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p><strong>prepare</strong></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>Before the submitted form is processed, but after
<em>prepareForSubmit</em></p></td><td colspan="1" rowspan="1"
class="confluenceTd">onPrepare()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.PREPARE</td></tr><tr><td cols
pan="1" rowspan="1"
class="confluenceTd"><p><strong>validate</strong></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>After fields have been populated from submitted values
and validated (e.g. perform cross-field validation)</p></td><td colspan="1"
rowspan="1" class="confluenceTd">onValidate</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.VALIDATE</td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong>validateForm</strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>same as <em>validate (deprecated – do
not use)<br clear="none"></em></p></td><td colspan="1" rowspan="1"
class="confluenceTd"><em>onValidateForm</em></td><td colspan="1" rowspan="1"
class="confluenceTd"> </td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><strong>failure</strong></p></td><td colspan=
"1" rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>After one or more validation errors have
occurred</p></td><td colspan="1" rowspan="1"
class="confluenceTd">onFailure()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.FAILURE</td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong>success</strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>When validation has completed
<em>without</em> any errors (e.g. save changes to the database)</p></td><td
colspan="1" rowspan="1" class="confluenceTd">onSuccess()</td><td colspan="1"
rowspan="1" class="confluenceTd">EventConstants.SUCCESS</td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p><strong>submit</strong></p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Submit</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>After all validation (s
uccess or failure) has finished</p></td><td colspan="1" rowspan="1"
class="confluenceTd">onSubmit()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.SUBMIT</td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><strong>canceled</strong></td><td colspan="1"
rowspan="1" class="confluenceTd">Submit</td><td colspan="1" rowspan="1"
class="confluenceTd">Whenever a <em>Submit</em> or <em>LinkSubmit</em>
component containing <em>mode="cancel"</em> or <em>mode="unconditional"</em> is
clicked</td><td colspan="1" rowspan="1"
class="confluenceTd">onCanceled()</td><td colspan="1" rowspan="1"
class="confluenceTd">EventConstants.CANCELED</td></tr></tbody></table></div><p>Note
that the "prepare" event is emitted during both form rendering and form
submission.</p><h2 id="FormsandValidation-HandlingEvents">Handling
Events</h2><p>Main Article: <a href="component-events.html">Component
Events</a></p><p>You handle events by providing methods in your page or
component class, ei
ther following the
on<strong><em>Event</em></strong>From<strong><em>Component</em></strong>()
naming convention or using the OnEvent annotation. For example:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader
panelHeader pdl" style="border-bottom-width: 1px;"><b>Event Handler Using
Naming Convention</b></div><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> void onValidateFromPassword() { ...}</pre>
</div></div><p>or the equivalent using @OnEvent:</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl"
style="border-bottom-width: 1px;"><b>Event Handler Using @OnEvent
Annotation</b></div><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> @OnEvent(value=EventConstants.VALIDATE,
component="password")
void verifyThePassword() { ...}</pre>
</div></div><h2 id="FormsandValidation-TrackingValidationErrors">Tracking
Validation Errors</h2><p>Associated with the Form is a <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ValidationTracker.html">ValidationTracker</a>
that tracks all the provided user input and validation errors for every field
in the form. The tracker can be provided to the Form via the Form's tracker
parameter, but this is rarely necessary.</p><p>The Form includes methods
<code>isValid()</code> and <code>getHasErrors()</code>, which are used to see
if the Form's validation tracker contains any errors.</p><p>In your own logic,
it is possible to record your own errors. Form includes two different versions
of method <code>recordError()</code>, one of which specifies a <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Field.html">Field</a>
(an interface implemented by all form element components), and one of which is
for
"global" errors, not associated with any particular field. If the error
concerns only a single field, you should use the first version so that the
field will be highlighted.</p><h2
id="FormsandValidation-StoringDataBetweenRequests">Storing Data Between
Requests</h2><p></p><div class="navmenu" style="float:right; width:40%;
background:white; margin:3px; padding:3px">
<div class="confluence-information-macro
confluence-information-macro-information"><p class="title">New in Tapestry
5.4</p><span class="aui-icon aui-icon-small aui-iconfont-info
confluence-information-macro-icon"></span><div
class="confluence-information-macro-body">
-<p>Starting in Tapestry 5.4, the default behavior for server-side validation
failures is to re-render the page within the same request (rather than emitting
a redirect). This removes the need to use a session-persistent field to store
the validation tracker when validation failures occur.</p></div></div></div>As
with other action requests, the result of a form submission (except when using
<a href="forms-and-validation.html">Zones</a>) is to send a redirect to the
client, which results in a second request (to re-render the page). The
ValidationTracker must be <a href="forms-and-validation.html">persisted</a>
(generally in the HttpSession) across these two requests in order to prevent
the loss of validation information. Fortunately, the default ValidationTracker
provided by the Form component is persistent, so you don't normally have to
worry about it.<p>However, for the same reason, the individual fields updated
by the components should also be persisted across requests, and this
is something you <strong>do</strong> need to do yourself – generally
with the @Persist annotation.</p><p>For example, a Login page class, which
collects a user name and a password, might look like:</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl"
style="border-bottom-width: 1px;"><b>Login.java Example</b></div><div
class="codeContent panelContent pdl">
+<p>Starting in Tapestry 5.4, the default behavior for server-side validation
failures is to re-render the page within the same request (rather than emitting
a redirect). This removes the need to use a session-persistent field to store
the validation tracker when validation failures occur.</p></div></div></div>As
with other action requests, the result of a form submission (except when using
<a href="forms-and-validation.html">Zones</a>) is to send a redirect to the
client, which results in a second request (to re-render the page). The
ValidationTracker must be <a href="persistent-page-data.html">persisted</a>
(generally in the HttpSession) across these two requests in order to prevent
the loss of validation information. Fortunately, the default ValidationTracker
provided by the Form component is persistent, so you don't normally have to
worry about it.<p>However, for the same reason, the individual fields updated
by the components should also be persisted across requests, and this
is something you <strong>do</strong> need to do yourself – generally
with the @Persist annotation.</p><p>For example, a Login page class, which
collects a user name and a password, might look like:</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl"
style="border-bottom-width: 1px;"><b>Login.java Example</b></div><div
class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">package com.example.newapp.pages;
@@ -224,10 +224,10 @@ public class Login {
@Property
@Validate("required")
private String password;</pre>
-</div></div><p>Now, we'll rebuild the app, refresh the browser, and just hit
enter:</p><p><span class="confluence-embedded-file-wrapper image-center-wrapper
confluence-embedded-manual-size"><img class="confluence-embedded-image
confluence-external-resource confluence-content-image-border image-center"
width="500"
src="https://cwiki-test.apache.org/confluence/download/attachments/22872109/newapp_com_example.png?version=3&modificationDate=1428088849000&api=v2"
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/22872109/newapp_com_example.png?version=3&modificationDate=1428088849000&api=v2"></span></p><p>The
form has updated, in place, to present the errors. You will not be able to
submit the form until some value is provided for each field.</p><h2
id="FormsandValidation-HTML5Client-sideValidation">HTML5 Client-side
Validation</h2><p>When
the <strong><code>tapestry.enable-html5-support</code></strong> <a
href="configuration.html">symbol<
/a> is set to true (it is <strong><em>false</em></strong> by default), the
Tapestry's built-in validators will automatically enable the HTML5-specific
"type" and validation attributes to the rendered HTML of Tapestry's form
components, triggering the HTML5 client-side validation behavior built into
most modern browsers. For example, if you use the "email" and "required"
validators, like 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;"><t:textfield validate="email,required" .../></pre>
+</div></div><p>Now, we'll rebuild the app, refresh the browser, and just hit
enter:</p><p><span class="confluence-embedded-file-wrapper image-center-wrapper
confluence-embedded-manual-size"><img class="confluence-embedded-image
confluence-external-resource confluence-content-image-border image-center"
width="500"
src="https://cwiki-test.apache.org/confluence/download/attachments/22872109/newapp_com_example.png?version=3&modificationDate=1428088849000&api=v2"
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/22872109/newapp_com_example.png?version=3&modificationDate=1428088849000&api=v2"></span></p><p>The
form has updated, in place, to present the errors. You will not be able to
submit the form until some value is provided for each field.</p><h2
id="FormsandValidation-HTML5Client-sideValidation">HTML5 Client-side
Validation</h2><p>When the <a
href="configuration.html"><code>tapestry.enable-html5-support</code></a> <span
class="conflue
nce-link">configuration symbol</span> is set to true (it is
<strong><em>false</em></strong> by default), the Tapestry's built-in validators
will automatically enable the HTML5-specific "type" and validation attributes
to the rendered HTML of Tapestry's form components, triggering the HTML5
client-side validation behavior built into most modern browsers. For example,
if you use the "email" and "required" validators, like this:</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 validate="email,required" .../></pre>
</div></div><p>then the output HTML will look like 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;"><input type="email" required ...></pre>
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><input type="email" required ...></pre>
</div></div><p>which causes modern browsers to present a validation error
message whenever text is entered that doesn't look like an email address, or if
the field is left blank.</p><p>The browser's built-in validation is performed
<em>before</em> Tapestry's own client-side validation. This is so that older
browsers will still perform client-side validation as expected.</p><p>The
following behaviors are included:</p><ul><li>The "<strong>required</strong>"
validator adds the "required" attribute to the rendered HTML</li><li>The
"<strong>regexp</strong>" validator adds the "pattern" attribute to the
rendered HTML</li><li>The "<strong>email</strong>" validator sets
the <code>type</code> attribute to "email" in the rendered
HTML</li><li>The "<strong>min</strong>" validator sets the <code>type</code>
attribute to "number" and adds the "min" attribute in the rendered
HTML</li><li>The "<strong>max</strong>" validator sets the <code>type</code>
attribute to "number" and adds the "max"
attribute in the rendered HTML</li><li>When bound to a <strong>number</strong>
type, the TextField component sets the <code>type</code> attribute to
"number" in the rendered HTML</li></ul><h2
id="FormsandValidation-ServerSideValidation">Server Side Validation</h2><p>Some
validation can't, or shouldn't, be done on the client side. How do we know if
the password is correct? Short of downloading all users and passwords to the
client, we really need to do the validation on the server.</p><p>In fact, all
client-side validation (via the validate parameter, or @Validate
annotation) is performed again on the server.</p><p>It is also possible to
perform extra validation there.</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;"> /**
* Do the cross-field validation
@@ -240,7 +240,7 @@ public class Login {
}
</pre>
-</div></div><p>This is the validate event handler from the loginForm
component. It is invoked once all the components have had a chance to read
values out of the request, do their own validations, and update the properties
they are bound to.</p><p>In this case, the authenticator is used to decide if
the userName and password is valid. In a real application, this would be where
a database or other external service was consulted.</p><p>If the combination is
not valid, then the password field is marked as in error. The form is used to
record an error, about a component (the passwordField) with an error
message.</p><p>Entering any two values into the form and submitting will cause
a round trip; the form will re-render to present the error to the
user:</p><p><span class="confluence-embedded-file-wrapper image-center-wrapper
confluence-embedded-manual-size"><img class="confluence-embedded-image
confluence-external-resource confluence-content-image-border image-center"
width="500" src="htt
ps://cwiki-test.apache.org/confluence/download/attachments/22872109/newapp_com_example.png?version=3&modificationDate=1428088849000&api=v2"
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/22872109/newapp_com_example.png?version=3&modificationDate=1428088849000&api=v2"></span></p><p>Notice
that the cursor is placed directly into the password field.</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 versions of Tapestry prior to
5.4, a form with validation errors would result in a redirect response to the
client; often, temporary server-side data (such as the userName field) would be
lost. Starting in 5.4, submitting a form with validation errors results in the
new page being rendered in the same request as the form
submission.</p></div></div><h2 id="FormsandVal
idation-CustomizingValidationMessages">Customizing Validation
Messages</h2><p>Each validator (such as "required" or "minlength") has a
default message used (on the client side and the server side) when the
constraint is violated; that is, when the user input is not valid.</p><p>The
message can be customized by adding an entry to the page's <a
href="forms-and-validation.html">message catalog</a> (or the containing
component's message catalog). As with any localized property, this can also go
into the application's message catalog.</p><p>The first key checked is
<em>formId</em>-<em>fieldId</em>-<em>validatorName</em>-message.</p><ul><li>formId:
the local component id of the Form component</li><li>fieldId: the local
component id of the field (TextField, etc.)</li><li>validatorName: the name of
the validator, i.e., "required" or "minlength"</li></ul><p>If there is no
message for that key, a second check is made, for
<em>fieldId</em>-<em>validatorName</em>-message. <span>If</span><
span> that does not match a message, then the built-in default validation
message is used.</span></p><p><span>For example, if the form ID is "loginForm",
the field ID is "userName", and the validator is "required" then Tapestry will
first look for a "loginForm-userName-required-message" key in the message
catalog, and then for a "<span>userName-required-message"
key.</span></span></p><p>The validation message in the message catalog may
contain <a class="external-link"
href="https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html"
rel="nofollow">printf-style format strings</a> (such as %s) to indicate
where the validate parameter's value will be inserted. For example, if the
validate parameter in the template is minLength=3 and the validation message is
"User name must be at least %s characters" then the corresponding error message
would be <span>"User name must be at least 5 characters".</span></p><h3
id="FormsandValidation-CustomizingValidationMessagesfor
BeanEditForm">Customizing Validation Messages for BeanEditForm</h3><p>The <a
href="forms-and-validation.html">BeanEditForm</a> component also supports
validation message customizing. The search for messages is similar; the
<em>formId</em> is the component id of the BeanEditForm component (not the Form
component it contains). The <em>fieldId</em> is the property name.</p><h2
id="FormsandValidation-ConfiguringValidatorContraintsintheMessageCatalog">Configuring
Validator Contraints in the Message Catalog</h2><p>It is possible to omit the
validation constraint from the validate parameter (or @Validator annotation),
in which case it is expected to be stored in the message catalog.</p><p>This is
useful when the validation constraint is awkward to enter inline, such as a
regular expression for use with the regexp validator.</p><p>The key here is
similar to customizing the validation message:
<em>formId</em>-<em>fieldId</em>-<em>validatorName</em> or just
<em>fieldId</em>-<em>validatorName
</em>.</p><p>For example, your template may have the following:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+</div></div><p>This is the validate event handler from the loginForm
component. It is invoked once all the components have had a chance to read
values out of the request, do their own validations, and update the properties
they are bound to.</p><p>In this case, the authenticator is used to decide if
the userName and password is valid. In a real application, this would be where
a database or other external service was consulted.</p><p>If the combination is
not valid, then the password field is marked as in error. The form is used to
record an error, about a component (the passwordField) with an error
message.</p><p>Entering any two values into the form and submitting will cause
a round trip; the form will re-render to present the error to the
user:</p><p><span class="confluence-embedded-file-wrapper image-center-wrapper
confluence-embedded-manual-size"><img class="confluence-embedded-image
confluence-external-resource confluence-content-image-border image-center"
width="500" src="htt
ps://cwiki-test.apache.org/confluence/download/attachments/22872109/newapp_com_example.png?version=3&modificationDate=1428088849000&api=v2"
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/22872109/newapp_com_example.png?version=3&modificationDate=1428088849000&api=v2"></span></p><p>Notice
that the cursor is placed directly into the password field.</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 versions of Tapestry prior to
5.4, a form with validation errors would result in a redirect response to the
client; often, temporary server-side data (such as the userName field) would be
lost. Starting in 5.4, submitting a form with validation errors results in the
new page being rendered in the same request as the form
submission.</p></div></div><h2 id="FormsandVal
idation-CustomizingValidationMessages">Customizing Validation
Messages</h2><p>Each validator (such as "required" or "minlength") has a
default message used (on the client side and the server side) when the
constraint is violated; that is, when the user input is not valid.</p><p>The
message can be customized by adding an entry to the page's <a
href="localization.html">message catalog</a> (or the containing component's
message catalog). As with any localized property, this can also go into the
application's message catalog.</p><p>The first key checked is
<em>formId</em>-<em>fieldId</em>-<em>validatorName</em>-message.</p><ul><li>formId:
the local component id of the Form component</li><li>fieldId: the local
component id of the field (TextField, etc.)</li><li>validatorName: the name of
the validator, i.e., "required" or "minlength"</li></ul><p>If there is no
message for that key, a second check is made, for
<em>fieldId</em>-<em>validatorName</em>-message. <span>If</span><span>
60;that does not match a message, then the built-in default validation message
is used.</span></p><p><span>For example, if the form ID is "loginForm", the
field ID is "userName", and the validator is "required" then Tapestry will
first look for a "loginForm-userName-required-message" key in the message
catalog, and then for a "<span>userName-required-message"
key.</span></span></p><p>The validation message in the message catalog may
contain <a class="external-link"
href="https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html"
rel="nofollow">printf-style format strings</a> (such as %s) to indicate
where the validate parameter's value will be inserted. For example, if the
validate parameter in the template is minLength=3 and the validation message is
"User name must be at least %s characters" then the corresponding error message
would be <span>"User name must be at least 5 characters".</span></p><h3
id="FormsandValidation-CustomizingValidationMessagesforBeanEdit
Form">Customizing Validation Messages for BeanEditForm</h3><p>The <a
href="beaneditform-guide.html">BeanEditForm</a> component also supports
validation message customizing. The search for messages is similar; the
<em>formId</em> is the component id of the BeanEditForm component (not the Form
component it contains). The <em>fieldId</em> is the property name.</p><h2
id="FormsandValidation-ConfiguringValidatorContraintsintheMessageCatalog">Configuring
Validator Contraints in the Message Catalog</h2><p>It is possible to omit the
validation constraint from the validate parameter (or @Validator annotation),
in which case it is expected to be stored in the message catalog.</p><p>This is
useful when the validation constraint is awkward to enter inline, such as a
regular expression for use with the regexp validator.</p><p>The key here is
similar to customizing the validation message:
<em>formId</em>-<em>fieldId</em>-<em>validatorName</em> or just
<em>fieldId</em>-<em>validatorName</em>.</p>
<p>For example, your template may have the following:</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="ssn"
validate="required,regexp"/>
</pre>
</div></div><p>And your message catalog can contain:</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
@@ -254,14 +254,14 @@ ssn-regexp-message=Social security numbe
<div class="aui-message aui-message-info">
Added in 5.2
 
-</div><p>Lists of validators can be combined into <em>validation macros</em>.
This mechanism is convenient for ensuring consistent validation rules across an
application. To create a validation macro, just contribute to the
ValidatorMacro Service in your module class (normally AppModule.java), by
adding a new entry to the configuration object, as shown below. The first
parameter is the name of your macro, the second is a comma-separated list of
validators:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+</div><p>Lists of validators can be combined into <em>validation macros</em>.
This mechanism is convenient for ensuring consistent validation rules across an
application. To create a validation macro, just contribute to the
ValidatorMacro Service in your module class (normally AppModule.java), by
adding a new entry to the configuration object, as shown below. The first
parameter is the name of your macro, the second is a comma-separated list of
validators:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>AppModule.java (partial)</b></div><div class="codeContent panelContent
pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">@Contribute(ValidatorMacro.class)
public static void combinePasswordValidators(MappedConfiguration<String,
String> configuration) {
- configuration.add("password","required,minlength=5,maxlength=15,");
+
configuration.add("passwordValidator","required,minlength=5,maxlength=15");
}
</pre>
</div></div><p>Then, you can use this new macro in component templates and
classes:</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 t:type="textField" t:id="password"
t:validate="password" />
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><input t:type="textField" t:id="password"
t:validate="passwordValidator" />
</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;">@Validate("password")
Modified: websites/production/tapestry/content/injection.html
==============================================================================
--- websites/production/tapestry/content/injection.html (original)
+++ websites/production/tapestry/content/injection.html Sun Feb 18 17:21:12 2018
@@ -119,7 +119,7 @@
</div>
-<p>Injection is a key concept in Tapestry, and it is used in several different
but related ways, listed below.</p><h2
id="Injection-InjectioninTapestryIOCServices">Injection in Tapestry IOC
Services</h2><p>Main Article: <a href="injection.html">Injection</a></p><p>The
Tapestry IoC container makes use of injection primarily through constructors
and via parameters to service builder methods.</p><h2
id="Injection-InjectioninComponentClasses">Injection in Component
Classes</h2><p>For components, however, Tapestry takes a completely different
tack: injection directly into component fields.</p><p>The @<a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html">Inject</a>
annotation is used to identify fields that will contain injected services and
other resources.</p><p>Tapestry allows for two kinds of
injection:</p><ul><li><strong>Default injection</strong>, where Tapestry
determines the object to inject into the field bas
ed on its type.</li><li><strong>Explicit injection</strong>, where the
particular service to be injected is specified.</li></ul><p>In both cases, the
field is transformed into a read only value. As elsewhere in Tapestry, this
transformation occurs at runtime (which is very important in terms of being
able to test your components). Attempting to update an injected field will
result in a runtime exception.</p><p>In addition, there are a few special cases
that are triggered by specific field types, or additional annotations, in
addition, to @Inject, on a field.</p><h3 id="Injection-BlockInjection">Block
Injection</h3><p>For field type <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Block.html">Block</a>,
the value of the Inject annotation is the id of the <a
href="injection.html"><t:block></a> element within the component's
template. Normally, the id of the block is determined from the field name
(after stripping out any leading "_
" and "$" characters):</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
+<p>Injection is a key concept in Tapestry, and it is used in several different
but related ways, listed below.</p><h2
id="Injection-InjectioninTapestryIOCServices">Injection in Tapestry IOC
Services</h2><p>Main Article: <a href="injection-in-detail.html">Injection in
Detail</a></p><p>The Tapestry IoC container makes use of injection primarily
through constructors and via parameters to service builder methods.</p><h2
id="Injection-InjectioninComponentClasses">Injection in Component
Classes</h2><p>For components, however, Tapestry takes a completely different
tack: injection directly into component fields.</p><p>The @<a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html">Inject</a>
annotation is used to identify fields that will contain injected services and
other resources.</p><p>Tapestry allows for two kinds of
injection:</p><ul><li><strong>Default injection</strong>, where Tapestry
determines the object to injec
t into the field based on its type.</li><li><strong>Explicit
injection</strong>, where the particular service to be injected is
specified.</li></ul><p>In both cases, the field is transformed into a read only
value. As elsewhere in Tapestry, this transformation occurs at runtime (which
is very important in terms of being able to test your components). Attempting
to update an injected field will result in a runtime exception.</p><p>In
addition, there are a few special cases that are triggered by specific field
types, or additional annotations, in addition, to @Inject, on a field.</p><h3
id="Injection-BlockInjection">Block Injection</h3><p>For field type <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Block.html">Block</a>,
the value of the Inject annotation is the id of the <span
class="confluence-link"><t:block></span> element within the component's
template. Normally, the id of the block is determined from the field name
(after s
tripping out any leading "_" and "$" characters):</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
private Block foo;
</pre>
@@ -132,7 +132,7 @@ private Block barBlock;
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">@Inject
private ComponentResources resources;
</pre>
-</div></div><p>Tapestry uses the type of the field, ComponentResources, to
determine what to inject into this field.</p><p>The following types are
supported for resources injection:</p><ul><li><strong>java.lang.String</strong>
– The complete id of the component, which incorporates the complete class
name of the containing page and the nested id of the component within the
page.</li></ul><ul><li><strong>java.util.Locale</strong> – The locale for
the component (all components within a page use the same
locale).</li></ul><ul><li><strong>org.slf4j.Logger</strong> – A Logger
instance configured for the component, based on the component's class name. <a
class="external-link" href="http://www.slf4j.org/" rel="nofollow">SLF4J</a> is
a wrapper around Log4J or other logging
toolkits.</li></ul><ul><li><strong>org.apache.tapestry5.ComponentResources</strong>
– The resources for the component, often used to generate links related
to the component.</li></ul><ul><li><stron
g>org.apache.tapestry5.ioc.Messages</strong> – The component message
catalog for the component, from which <a href="injection.html">localized</a>
messages can be generated.</li></ul><h3 id="Injection-AssetInjection">Asset
Injection</h3><p>Main Article: <a
href="injection.html">Injection</a></p><p>When the @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Path.html">Path</a>
annotation is also present, then the injected value (relative to the
component) will be a localized asset.</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p>Tapestry uses the type of the field, ComponentResources, to
determine what to inject into this field.</p><p>The following types are
supported for resources injection:</p><ul><li><strong>java.lang.String</strong>
– The complete id of the component, which incorporates the complete class
name of the containing page and the nested id of the component within the
page.</li></ul><ul><li><strong>java.util.Locale</strong> – The locale for
the component (all components within a page use the same
locale).</li></ul><ul><li><strong>org.slf4j.Logger</strong> – A Logger
instance configured for the component, based on the component's class name. <a
class="external-link" href="http://www.slf4j.org/" rel="nofollow">SLF4J</a> is
a wrapper around Log4J or other logging
toolkits.</li></ul><ul><li><strong>org.apache.tapestry5.ComponentResources</strong>
– The resources for the component, often used to generate links related
to the component.</li></ul><ul><li><stron
g>org.apache.tapestry5.ioc.Messages</strong> – The component message
catalog for the component, from which <a href="injection.html">localized</a>
messages can be generated.</li></ul><h3 id="Injection-AssetInjection">Asset
Injection</h3><p>Main Article: <a href="assets.html">Assets</a></p><p>When the
@<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Path.html">Path</a>
annotation is also present, then the injected value (relative to the
component) will be a localized asset.</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
@Path("context:images/top_banner.png")
private Asset banner;
@@ -154,7 +154,7 @@ private EmployeeService employeeService;
@Service("Request")
private Request request;
</pre>
-</div></div><p>This is generally not necessary; you should always be able to
identify the service to be injected just by type, not by explicit id. Explicit
ids have the disadvantage of not being refactoring-safe: this won't happen with
the Request service, but perhaps in your own code ... if you rename the service
interface and rename the service id to match, your existing injections using
the explicit service id will break.</p><h2
id="Injection-DefaultInjection">Default Injection</h2><p>When the type and/or
other annotations are not sufficient to identify the object or service to
inject, Tapestry falls back on two remaining steps. It assumes that the field
type will be used to identify a service, by the service interface.</p><p>First,
the object provider created by the Alias service is consulted. This object
provider is used to disambiguate injections when there is more than one service
that implements the same service interface.</p><p>Second, a search for a unique
service that imp
lements the interface occurs. This will fail if either there are no services
that implement the interface, or there is more than one. In the latter case,
you must disambiguate, either with a contribution to the Alias service, or by
explicitly identifying the service with the @Service annotation.</p><h2
id="Injection-DefiningNewInjectionLogic">Defining New Injection
Logic</h2><p>Anonymous injection is controlled by the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/InjectionProvider.html">InjectionProvider</a>
service. The configuration for this service is a <a
href="injection.html">chain of command</a> for handling component
injections.</p></div>
+</div></div><p>This is generally not necessary; you should always be able to
identify the service to be injected just by type, not by explicit id. Explicit
ids have the disadvantage of not being refactoring-safe: this won't happen with
the Request service, but perhaps in your own code ... if you rename the service
interface and rename the service id to match, your existing injections using
the explicit service id will break.</p><h2
id="Injection-DefaultInjection">Default Injection</h2><p>When the type and/or
other annotations are not sufficient to identify the object or service to
inject, Tapestry falls back on two remaining steps. It assumes that the field
type will be used to identify a service, by the service interface.</p><p>First,
the object provider created by the Alias service is consulted. This object
provider is used to disambiguate injections when there is more than one service
that implements the same service interface.</p><p>Second, a search for a unique
service that imp
lements the interface occurs. This will fail if either there are no services
that implement the interface, or there is more than one. In the latter case,
you must disambiguate, either with a contribution to the Alias service, or by
explicitly identifying the service with the @Service annotation.</p><h2
id="Injection-DefiningNewInjectionLogic">Defining New Injection
Logic</h2><p>Anonymous injection is controlled by the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/InjectionProvider.html">InjectionProvider</a>
service. The configuration for this service is a <a
href="chainbuilder-service.html">chain of command</a> for handling component
injections.</p></div>
</div>
<div class="clearer"></div>