Author: buildbot
Date: Sat Aug 17 18:20:32 2013
New Revision: 875040

Log:
Production update by buildbot for tapestry

Modified:
    websites/production/tapestry/content/cache/main.pageCache
    websites/production/tapestry/content/using-select-with-a-list.html

Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.

Modified: websites/production/tapestry/content/using-select-with-a-list.html
==============================================================================
--- websites/production/tapestry/content/using-select-with-a-list.html 
(original)
+++ websites/production/tapestry/content/using-select-with-a-list.html Sat Aug 
17 18:20:32 2013
@@ -34,9 +34,9 @@
 </div>
 
 <div id="top">
-<div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 
1em .1em 1em">
+<div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 
1em .1em 1em"><p>
 <span style="color: #999; font-size: 90%">Tapestry docs, issues, wikis &amp; 
blogs:</span>
-<form enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";>
+</p><form enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";>
   <input type="text" name="q">
   <input type="submit" value="Search">
 </form>
@@ -72,9 +72,9 @@ table.ScrollbarTable td.ScrollbarNextIco
 <p>The documentation for the <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Select.html";>Select
 Component</a> and the <a shape="rect" href="tutorial.html" 
title="Tutorial">Tapestry Tutorial</a> provide simplistic examples of 
populating a drop-down menu (as the (X)HTML <em>Select</em> element) using 
comma-delimited strings and enums. However, most real-world Tapestry 
applications need to populate such menus using values from a database, commonly 
in the form of java.util.List objects. Doing so generally requires a <a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/SelectModel.html";>SelectModel</a>
 and a <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ValueEncoder.html";>ValueEncoder</a>
 bound to the Select component with its "model" and "encoder" parameters:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeContent 
panelContent">
-<pre class="code-java">
-&lt;t:select t:id=<span class="code-quote">"colorMenu"</span> value=<span 
class="code-quote">"selectedColor"</span> model=<span 
class="code-quote">"ColorSelectModel"</span> encoder=<span 
class="code-quote">"colorEncoder"</span> /&gt;
-</pre>
+<script class="theme: Default; brush: java; gutter: false" 
type="syntaxhighlighter"><![CDATA[
+&lt;t:select t:id="colorMenu" value="selectedColor" model="ColorSelectModel" 
encoder="colorEncoder" /&gt;
+]]></script>
 </div></div>
 
 <p>In the above example, ColorSelectModel must be of type SelectModel, or 
anything that Tapestry knows how to <a shape="rect" href="type-coercion.html" 
title="Type Coercion">coerce</a> into a SelectModel, such as a List or a Map or 
a "value=label,value=label,..." delimited string, or anything Tapestry knows 
how to coerce into a List or Map, such as an Array or a comma-delimited 
String.</p>
@@ -92,32 +92,32 @@ table.ScrollbarTable td.ScrollbarNextIco
 <p>To have Tapestry create a SelectModel for you, use the <a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/SelectModelFactory.html";>SelectModelFactory</a>
 service. SelectModelFactory creates a SelectModel from a List of objects (of 
whatever type) and a label property name that you choose:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>SelectWithListDemo.java (a 
page class)</b></div><div class="codeContent panelContent">
-<pre class="code-java">
+<script class="theme: Default; brush: java; gutter: false" 
type="syntaxhighlighter"><![CDATA[
 @Property
-<span class="code-keyword">private</span> SelectModel colorSelectModel;
+private SelectModel colorSelectModel;
 @Inject
 SelectModelFactory selectModelFactory;
 ...
 void setupRender() {
-    <span class="code-comment">// invoke my service to find all colors, e.g. 
in the database
-</span>    List&lt;Color&gt; colors = colorService.findAll();
+    // invoke my service to find all colors, e.g. in the database
+    List&lt;Color&gt; colors = colorService.findAll();
 
-    <span class="code-comment">// create a SelectModel from my list of colors
-</span>    colorSelectModel = selectModelFactory.create(colors, <span 
class="code-quote">"name"</span>);
+    // create a SelectModel from my list of colors
+    colorSelectModel = selectModelFactory.create(colors, "name");
 }
-</pre>
+]]></script>
 </div></div>
 
-<p>The resulting SelectModel has a selectable option (specifically, an 
OptionModel) for every object in the original List. The label property name 
(the "name" property, in this example) determines the user-visible text of each 
menu option, and your ValueEncoder's toClient() method provides the encoded 
value (most commonly a simple number). If you don't provide a ValueEncoder, the 
result of the objects' toString() method (Color.toString() in this example) is 
used. Although not a recommended practice, you <em>could</em> set your 
toString() to return the object's ID for this purpose:</p>
+<p>The resulting SelectModel has a selectable option (specifically, an 
OptionModel) for every object in the original List. The label property name 
(the "name" property, in this example) determines the user-visible text of each 
menu option, and your ValueEncoder's toClient() method provides the encoded 
value (most commonly a simple number). If you don't provide a ValueEncoder, the 
result of the objects' toString() method (Color#toString() in this example) is 
used. Although not a recommended practice, you <em>could</em> set your 
toString() to return the object's ID for this purpose:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>Color.java 
(partial)</b></div><div class="codeContent panelContent">
-<pre class="code-java">
+<script class="theme: Default; brush: java; gutter: false" 
type="syntaxhighlighter"><![CDATA[
 ...
 @Override
-<span class="code-keyword">public</span> <span 
class="code-object">String</span> toString() {
-    <span class="code-keyword">return</span> <span 
class="code-object">String</span>.valueOf(<span 
class="code-keyword">this</span>.getId()); 
+public String toString() {
+    return String.valueOf(this.getId()); 
 }
-</pre>
+]]></script>
 </div></div>
 
 <p>But that is contorting the purpose of the toString() method, and if you go 
to that much trouble you're already half way to the recommended practice: 
creating a ValueEncoder.</p>
@@ -126,6 +126,9 @@ void setupRender() {
 
 <p>In addition to a SelectModel, your Select menu is likely to need a 
ValueEncoder. While a SelectModel is concerned only with how to construct a 
Select menu, a ValueEncoder is used when constructing the Select menu 
<em>and</em> when interpreting the encoded value that is submitted back to the 
server. A ValueEncoder is a converter between the type of objects you want to 
represent as options in the menu and the client-side encoded values that 
uniquely identify them, and vice-versa.</p>
 
+<div class="navmenu" style="float:right; background:#eee; margin:3px; 
padding:0 1em"><p>    <b>JumpStart Demo:</b><br clear="none">
+    <a shape="rect" class="external-link" 
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/select/easyobject";
 >Easy Object Select</a></p></div>
+
 <p>Most commonly, your ValueEncoder's toClient() method will return a unique 
ID (e.g. a database primary key, or perhaps a UUID) of the given object, and 
its toValue() method will return the <em>object</em> matching the given ID by 
doing a database lookup (ideally using a service or DAO method).</p>
 
 <p>If you're using one of the ORM integration modules (<a shape="rect" 
href="hibernate.html" title="Hibernate">Tapestry-Hibernate</a>, <a shape="rect" 
href="integrating-with-jpa.html" title="Integrating with JPA">Tapestry-JPA</a>, 
or <a shape="rect" class="external-link" 
href="http://code.google.com/p/tapestry5-cayenne/wiki/ValueEncoder"; 
>Tapestry-Cayenne</a>), the ValueEncoder is automatically provided for each of 
your mapped entity classes. The Hibernate module's implementation is typical: 
the primary key field of the object (converted to a String) is used as the 
client-side value, and that same primary key is used to look up the selected 
object. </p>
@@ -133,57 +136,57 @@ void setupRender() {
 <p>That's exactly what you should do in your own ValueEncoders too:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>ColorEncoder.java (perhaps in 
your com.example.myappname.encoders package)</b></div><div class="codeContent 
panelContent">
-<pre class="code-java">
-<span class="code-keyword">public</span> class ColorEncoder <span 
class="code-keyword">implements</span> ValueEncoder&lt;Color&gt;, 
ValueEncoderFactory&lt;Color&gt; { 
+<script class="theme: Default; brush: java; gutter: false" 
type="syntaxhighlighter"><![CDATA[
+public class ColorEncoder implements ValueEncoder&lt;Color&gt;, 
ValueEncoderFactory&lt;Color&gt; { 
 
     @Inject
-    <span class="code-keyword">private</span> ColorService colorService;
+    private ColorService colorService;
 
     @Override
-    <span class="code-keyword">public</span> <span 
class="code-object">String</span> toClient(Color value) {
-        <span class="code-comment">// <span class="code-keyword">return</span> 
the given object's ID
-</span>        <span class="code-keyword">return</span> <span 
class="code-object">String</span>.valueOf(value.getId()); 
+    public String toClient(Color value) {
+        // return the given object's ID
+        return String.valueOf(value.getId()); 
     }
 
     @Override
-    <span class="code-keyword">public</span> Color toValue(<span 
class="code-object">String</span> id) { 
-        <span class="code-comment">// find the color object of the given ID in 
the database
-</span>        <span class="code-keyword">return</span> 
colorService.findById(<span class="code-object">Long</span>.parseLong(id)); 
+    public Color toValue(String id) { 
+        // find the color object of the given ID in the database
+        return colorService.findById(Long.parseLong(id)); 
     }
 
-    <span class="code-comment">// let <span class="code-keyword">this</span> 
ValueEncoder also serve as a ValueEncoderFactory
-</span>    @Override
-    <span class="code-keyword">public</span> ValueEncoder&lt;Color&gt; 
create(<span class="code-object">Class</span>&lt;Color&gt; type) {
-        <span class="code-keyword">return</span> <span 
class="code-keyword">this</span>; 
+    // let this ValueEncoder also serve as a ValueEncoderFactory
+    @Override
+    public ValueEncoder&lt;Color&gt; create(Class&lt;Color&gt; type) {
+        return this; 
     }
 } 
-</pre>
+]]></script>
 </div></div>
 
 <p>Alternatively, if you don't expect to need a particular ValueEncoder more 
than once in your app, you might want to just create it on demand, using an 
anonymous inner class, from the getter method in the component class where it 
is needed. For example:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>SelectWithListDemo.java (a 
page class, partial)</b></div><div class="codeContent panelContent">
-<pre class="code-java">
+<script class="theme: Default; brush: java; gutter: false" 
type="syntaxhighlighter"><![CDATA[
     . . .
 
-    <span class="code-keyword">public</span> ValueEncoder&lt;Color&gt; 
getColorEncoder() {
+    public ValueEncoder&lt;Color&gt; getColorEncoder() {
 
-        <span class="code-keyword">return</span> <span 
class="code-keyword">new</span> ValueEncoder&lt;Color&gt;() {
+        return new ValueEncoder&lt;Color&gt;() {
 
             @Override
-            <span class="code-keyword">public</span> <span 
class="code-object">String</span> toClient(Color value) {
-                <span class="code-comment">// <span 
class="code-keyword">return</span> the given object's ID
-</span>                <span class="code-keyword">return</span> <span 
class="code-object">String</span>.valueOf(value.getId()); 
+            public String toClient(Color value) {
+                // return the given object's ID
+                return String.valueOf(value.getId()); 
             }
 
             @Override
-            <span class="code-keyword">public</span> Color toValue(<span 
class="code-object">String</span> id) { 
-                <span class="code-comment">// find the color object of the 
given ID in the database
-</span>                <span class="code-keyword">return</span> 
colorService.findById(<span class="code-object">Long</span>.parseLong(id)); 
+            public Color toValue(String id) { 
+                // find the color object of the given ID in the database
+                return colorService.findById(Long.parseLong(id)); 
             }
         }; 
     }
-</pre>
+]]></script>
 </div></div>
 
 <p>Notice that the body of this anonymous inner class is the same as the body 
of the ColorEncoder top level class, except that we don't need a 
<tt>create</tt> method.</p>
@@ -193,27 +196,27 @@ void setupRender() {
 <p>If your ValueEncoder <em>implements ValueEncoderFactory</em> (as the 
ColorEncoder top level class does, above), you can associate your custom 
ValueEncoder with your entity class so that Tapestry will automatically use it 
every time a ValueEncoder is needed for items of that type (such as with the 
Select, RadioGroup, Grid, Hidden and AjaxFormLoop components). Just add lines 
like the following to your module class (usually AppModule.java):</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>AppModule.java 
(partial)</b></div><div class="codeContent panelContent">
-<pre class="code-java">
+<script class="theme: Default; brush: java; gutter: false" 
type="syntaxhighlighter"><![CDATA[
 ...
-    <span class="code-keyword">public</span> <span 
class="code-keyword">static</span> void 
contributeValueEncoderSource(MappedConfiguration&lt;<span 
class="code-object">Class</span>&lt;Color&gt;,
+    public static void 
contributeValueEncoderSource(MappedConfiguration&lt;Class&lt;Color&gt;,
                         ValueEncoderFactory&lt;Color&gt;&gt; configuration) { 
         configuration.addInstance(Color.class, ColorEncoder.class);
     }
-</pre>
+]]></script>
 </div></div>
 
 <p>If you are contributing more than one ValueEncoder, you'll have to use raw 
types, like this:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>AppModule.java 
(partial)</b></div><div class="codeContent panelContent">
-<pre class="code-java">
+<script class="theme: Default; brush: java; gutter: false" 
type="syntaxhighlighter"><![CDATA[
 ...
-    <span class="code-keyword">public</span> <span 
class="code-keyword">static</span> void 
contributeValueEncoderSource(MappedConfiguration&lt;<span 
class="code-object">Class</span>,
+    public static void 
contributeValueEncoderSource(MappedConfiguration&lt;Class,
                         ValueEncoderFactory&gt; configuration)
     {
         configuration.addInstance(Color.class, ColorEncoder.class);
         configuration.addInstance(SomeOtherType.class, 
SomeOtherTypeEncoder.class);
     }
-</pre>
+]]></script>
 </div></div>
 
 
@@ -222,31 +225,31 @@ void setupRender() {
 <p>The Select component's "encoder" parameter is optional, but if the "value" 
parameter is bound to a complex object (not a simple String, Integer, etc.) and 
you don't provide a ValueEncoder with the "encoder" parameter (and one isn't 
provided automatically by, for example, the Tapestry Hibernate integration), 
you'll receive a "Could not find a coercion" exception (when you submit the 
form) as Tapestry tries to convert the selected option's encoded value back to 
the <em>object</em> in your Select's "value" parameter. To fix this, you'll 
either have to 1) provide a ValueEncoder, 2) provide a <a shape="rect" 
href="typecoercer-service.html" title="TypeCoercer Service">Coercion</a>, or 3) 
use a simple value (String, Integer, etc.) for your Select's "value" parameter, 
and then you'll have to add logic in the corresponding onSuccess event listener 
method:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>SelectWithListDemo.tml 
(partial)</b></div><div class="codeContent panelContent">
-<pre class="code-java">
-&lt;t:select t:id=<span class="code-quote">"colorMenu"</span> value=<span 
class="code-quote">"selectedColorId"</span> model=<span 
class="code-quote">"ColorSelectModel"</span> /&gt;
-</pre>
+<script class="theme: Default; brush: java; gutter: false" 
type="syntaxhighlighter"><![CDATA[
+&lt;t:select t:id="colorMenu" value="selectedColorId" model="ColorSelectModel" 
/&gt;
+]]></script>
 </div></div>
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>SelectWithListDemo.java 
(partial)</b></div><div class="codeContent panelContent">
-<pre class="code-java">
+<script class="theme: Default; brush: java; gutter: false" 
type="syntaxhighlighter"><![CDATA[
 ...
-    <span class="code-keyword">public</span> void onSuccessFromMyForm() {
-        <span class="code-comment">// look up the color object from the ID 
selected
-</span>        selectedColor = colorService.findById(selectedColorId);
+    public void onSuccessFromMyForm() {
+        // look up the color object from the ID selected
+       selectedColor = colorService.findById(selectedColorId);
        ...
     }
-</pre>
+]]></script>
 </div></div>
 
 <p>But then again, you may as well create a ValueEncoder instead.</p>
 
 <h2><a shape="rect" name="UsingSelectWithaList-Whyisthissohard%3F"></a>Why is 
this so hard?</h2>
 
-<p>Actually, it's really pretty easy if you follow the examples above. But why 
is Tapestry designed to use SelectModels and ValueEncoders anyway? Well, in 
short, this design allows you to avoid storing (via @Persist, @SessionAttribute 
or @SessionState) the entire (potentially large) list of objects in the session 
or rebuilding the whole list of objects again (though only one is needed) when 
the form is submitted. The chief benefits are reduced memory use and <a 
shape="rect" class="external-link" 
href="http://thread.gmane.org/gmane.comp.java.tapestry.user/65410/focus=65426"; 
>more scalable clustering</a> due to having far less HTTP session data to 
replicate across the nodes of a cluster.</p></div>
+<p>Actually, it's really pretty easy if you follow the examples above. But why 
is Tapestry designed to use SelectModels and ValueEncoders anyway? Well, in 
short, this design allows you to avoid storing (via @Persist, @SessionAttribute 
or @SessionState) the entire (potentially large) list of objects in the session 
or rebuilding the whole list of objects again (though only one is needed) when 
the form is submitted. The chief benefits are reduced memory use and <a 
shape="rect" href="performance-and-clustering.html" title="Performance and 
Clustering">more scalable clustering</a> due to having far less HTTP session 
data to replicate across the nodes of a cluster.</p></div>
 </div>
 
 <div class="clearer"></div>
 <div id="footer">
-<div id="footer"><p>Apache Tapestry, Tapestry, Apache, the Apache feather 
logo, and the Apache Tapestry project logo are trademarks of The Apache 
Software Foundation.</p>
+<div id="footer"><p>Apache Tapestry, Tapestry, Apache, the Apache feather 
logo, and the Apache Tapestry project logo are trademarks of The Apache 
Software Foundation.<br clear="none">
 <script type="text/javascript">
   var _gaq = _gaq || [];
   _gaq.push(['_setAccount', 'UA-400821-1']);
@@ -257,7 +260,7 @@ void setupRender() {
     ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 
'http://www') + '.google-analytics.com/ga.js';
     var s = document.getElementsByTagName('script')[0]; 
s.parentNode.insertBefore(ga, s);
   })();
-</script></div>
+</script></p></div>
 </div>
                <div id="comments_thread"></div>
                <script type="text/javascript" 
src="https://comments.apache.org/show_comments.lua?site=tapestry&amp;page=http://tapestry.apache.org/using-select-with-a-list.html";
 async="true">


Reply via email to