Is the way I'm building my custom select model the "approved" Tap 5
way? My concern is if OptionModelImpl and SelectModelImpl are still
considered internal Tapestry classes and should be avoided? This stuff
works fine for me and it's fairly elegant (IMHO), I just want to know
if there is a better way.

        <div class="w-row">
        <div class="w-tlabel"><t:label for="article" />:</div>
        <t:select t:id="article" style="width:60%;" t:value="articleId"
t:model="articlesModel" /></div>


        @Cached
        public SelectModel getArticlesModel() {
                
                final List<SelfHelpArticleBean> articles = getArticles();
                
                return new SelectModel() {

                        private final SelectModel model;
                        
                        {
                                OptionModel[] options = new 
OptionModel[articles.size()+1];
                                options[0] = new OptionModelImpl("-- Please 
Select", 0);
                                int index = 1;
                                for(SelfHelpArticleBean article : articles) {
                                        String label = article.getId() +
                                                                        ": " + 
article.getAnchorBody();
                                        int value = article.getId();
                                        options[index++] = new 
OptionModelImpl(label, value);
                                }
                                
                                model = new SelectModelImpl(options);
                        }
                        
                        public List<OptionGroupModel> getOptionGroups() {
                                return model.getOptionGroups();
                        }

                        public List<OptionModel> getOptions() {
                                return model.getOptions();
                        }

                        public void visit(SelectModelVisitor aVisitor) {
                                model.visit(aVisitor);
                        }
                        
                };
        }


On Tue, May 8, 2007 at 12:50 AM, Bill Holloway <[EMAIL PROTECTED]> wrote:
> I'm just hoping for a stable, best-practice, and relatively simple way
>  to set things up like Selects.  Whatever you think is the best
>  approach and put in the documentation.
>
>  Things like selects should be a snap, IMHO.
>
>  Bill
>
>
>
>  On 5/7/07, Howard Lewis Ship <[EMAIL PROTECTED]> wrote:
>  > My approach has to been to keep everything internal if possible. Thus an
>  > interface is public, the implementation is internal.
>  >
>  > If something is truly necessary, such as OptionModelImpl, there are two
>  > approaches:
>  >
>  > 1) Make the implementation class public (possibly breaking existing code
>  > that extends from the internal class) .... oh, and probably make it final 
> as
>  > well.
>  >
>  > 2) Define a public factory service for the implementation.
>  >
>  > Right now, you can actually use the TypeCoercer as a kind of factory; if 
> you
>  > pass in a comma-separated string and ask for an SelectModel you'll get it.
>  > Here, though, you're looking for something a little better adapted to your
>  > entity classes.  However, a bare-bones implementation of OptionModel (that
>  > always returns false for isDisabled(), and null for getAttributes() ) is
>  > only a couple of lines of code.
>  >
>  > I think T4 fell into a trap of too much convenience stuff exposed as public
>  > APIs.  I would rather err on the side of over-zealousness for T5.  You can
>  > take internals public, but not the other way around, and once something is
>  > public, it also is (or should be) final.
>  >
>  > On 5/7/07, Bill Holloway <[EMAIL PROTECTED]> wrote:
>  > >
>  > > I've written similar code -- while remembering that OptionModelImpl is
>  > > an "internal" class that Howard, in the documentation, has admonished
>  > > us not to use.
>  > >
>  > > Community, what's the better solution?
>  > >
>  > > Bill
>  > >
>  > > On 5/7/07, Joel Wiegman <[EMAIL PROTECTED]> wrote:
>  > > > Eureka!
>  > > >
>  > > > Finally got it all working.  What caused the drop down to not be
>  > > > defaulting is the fact that I declared my "Brand" list in two separate
>  > > > lists... One for the ValueEncoder and one for the SelectModel.  Big no
>  > > > no!  An "equals" is called on the value from the SelectModel and the
>  > > > value from the ValueEncoder, so if they are initialized as separate
>  > > > objects in separate lists the framework won't notice that they are 
> equal
>  > > > (because they would point to a different memory location).  I found 
> that
>  > > > the framework also seems to like things better if the List of Brands is
>  > > > "@Persist"ed between pages.  Here's the final source code that I used 
> to
>  > > > get it all working (Enjoy!):
>  > > >
>  > > > Brand.java (simple POJO):
>  > > >
>  > > > public class Brand {
>  > > >
>  > > >         private String id;
>  > > >         private String description;
>  > > >
>  > > >         public Brand() {}
>  > > >
>  > > >         public Brand(String id, String description) {
>  > > >                 this.id = id;
>  > > >                 this.description = description;
>  > > >         }
>  > > >
>  > > >         public String getId() {
>  > > >                 return id;
>  > > >         }
>  > > >
>  > > >         public String getDescription() {
>  > > >                 return description;
>  > > >         }
>  > > >
>  > > > }
>  > > >
>  > > >
>  > > > Test.java
>  > > >
>  > > > public class Test {
>  > > >
>  > > >         @Persist
>  > > >         private Brand brand;
>  > > >
>  > > >         @Persist
>  > > >         private List<Brand> brands;
>  > > >
>  > > >         public Brand getBrand() {
>  > > >                 return brand;
>  > > >         }
>  > > >
>  > > >         public void setBrand(Brand brand) {
>  > > >                 this.brand = brand;
>  > > >         }
>  > > >
>  > > >         private List<Brand> getBrands()
>  > > >         {
>  > > >                 if(brands == null) {
>  > > >                         brands = new ArrayList<Brand>();
>  > > >                         brands.add(new Brand("1", "Brand 1"));
>  > > >                         brands.add(new Brand("2", "Brand 2"));
>  > > >                         brands.add(new Brand("3", "Brand 3"));
>  > > >                         brands.add(new Brand("4", "Brand 4"));
>  > > >                 }
>  > > >
>  > > >                 return brands;
>  > > >         }
>  > > >
>  > > >         public BrandSelectModel getBrandSelectModel() {
>  > > >                 return new BrandSelectModel(getBrands());
>  > > >         }
>  > > >
>  > > >         public BrandValueEncoder getBrandValueEncoder() {
>  > > >                 return new BrandValueEncoder(getBrands());
>  > > >         }
>  > > >
>  > > >         public class BrandValueEncoder implements ValueEncoder<Brand> {
>  > > >
>  > > >                 private List<Brand> brands;
>  > > >
>  > > >                 public BrandValueEncoder(List<Brand> brands) {
>  > > >                         this.brands = brands;
>  > > >                 }
>  > > >
>  > > >                 public String toClient(Brand brand) {
>  > > >                         return brand.getDescription();
>  > > >                 }
>  > > >
>  > > >                 public Brand toValue(String string) {
>  > > >                         for(Brand brand : brands) {
>  > > >
>  > > > if(brand.getDescription().equals(string)) {
>  > > >                                         return brand;
>  > > >                                 }
>  > > >                         }
>  > > >                         return null;
>  > > >                 }
>  > > >
>  > > >         }
>  > > >
>  > > >         public class BrandSelectModel implements SelectModel {
>  > > >
>  > > >                 private List<Brand> brands;
>  > > >
>  > > >                 public BrandSelectModel(List<Brand> brands) {
>  > > >                         this.brands = brands;
>  > > >                 }
>  > > >
>  > > >                 public List<OptionGroupModel> getOptionGroups() {
>  > > >                         return null;
>  > > >                 }
>  > > >
>  > > >                 public List<OptionModel> getOptions() {
>  > > >                         List<OptionModel> optionModelList = new
>  > > > ArrayList<OptionModel>();
>  > > >                         for(Brand brand: brands) {
>  > > >                                 optionModelList.add(
>  > > >                                         new OptionModelImpl(
>  > > >                                                 brand.getDescription(),
>  > > >                                                 false,
>  > > >                                                 brand,
>  > > >                                                 new String[0]
>  > > >                                         )
>  > > >                                 );
>  > > >                         }
>  > > >                         return optionModelList;
>  > > >                 }
>  > > >
>  > > >         }
>  > > >
>  > > > }
>  > > >
>  > > >
>  > > > Test.html
>  > > >
>  > > > <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";>
>  > > > <t:form>
>  > > >
>  > > >         <select t:type="select" t:id="brand"
>  > > >                 value="brand" model="brandSelectModel"
>  > > > encoder="brandValueEncoder"
>  > > >                 onchange="this.form.submit();" />
>  > > >
>  > > >         <br/>
>  > > >
>  > > >         <t:if test="brand">
>  > > >                 ${brand.description}
>  > > >         </t:if>
>  > > >
>  > > > </t:form>
>  > > > </html>
>  > > >
>  > > >
>  > > > -----Original Message-----
>  > > > From: Howard Lewis Ship [mailto:[EMAIL PROTECTED]
>  > > > Sent: Monday, May 07, 2007 12:17 PM
>  > > > To: Tapestry users
>  > > > Subject: Re: T5: SelectModel - a real world example
>  > > >
>  > > > Odd that you lost your value; the field is itself persistent 
> (@Persist).
>  > > > Unless you are testing on a multi-machine cluster, you shouldn't see 
> any
>  > > > problems along these lines!
>  > > >
>  > > > On 5/7/07, Joel Wiegman <[EMAIL PROTECTED]> wrote:
>  > > > >
>  > > > > Impressive!  I was injecting that value via Spring to bootstrap it.
>  > > > > Makes sense I should have removed that...
>  > > > >
>  > > > > No errors now...  However, the field doesn't appear to be binding on 
> a
>  > > >
>  > > > > form submission.  The encoder and the model appear to be receiving 
> and
>  > > >
>  > > > > returning the correct values, the brand getter and setter appear to 
> be
>  > > >
>  > > > > getting called, and the dropdown renders correctly except that it
>  > > > > always appears to be reset to the default value...
>  > > > >
>  > > > > I apologize for being so high-maintenance.  If there is a working
>  > > > > example of a T5 binding select box anywhere on the web, please point
>  > > > > me there and I will leave you alone!
>  > > > >
>  > > > > Main.html
>  > > > >
>  > > > > <t:form>
>  > > > >   <select t:type="select" class="mint_font_black_background"
>  > > > > t:id="brand"
>  > > > >     value="brand" model="brandSelectModel" 
> encoder="brandValueEncoder"
>  > > > >     onchange="this.form.submit();" />
>  > > > > </t:form>
>  > > > >
>  > > > >
>  > > > > Main.java
>  > > > >
>  > > > > public class Main {
>  > > > >
>  > > > >         @Inject
>  > > > >         @SpringBean("enterprise")
>  > > > >         private Enterprise enterprise;
>  > > > >
>  > > > >         @Persist
>  > > > >         private Brand brand;
>  > > > >
>  > > > >         public Brand getBrand() {
>  > > > >                 return brand;
>  > > > >         }
>  > > > >
>  > > > >         public void setBrand(Brand brand) {
>  > > > >                 this.brand = brand;
>  > > > >         }
>  > > > >
>  > > > >         public BrandSelectModel getBrandSelectModel() {
>  > > > >                 return new BrandSelectModel(enterprise.getBrands());
>  > > > >         }
>  > > > >
>  > > > >         public BrandValueEncoder getBrandValueEncoder() {
>  > > > >                 return new BrandValueEncoder(enterprise.getBrands());
>  > > > >         }
>  > > > >
>  > > > >         public class BrandValueEncoder implements ValueEncoder<Brand>
>  > > > > {
>  > > > >
>  > > > >                 private List<Brand> brands;
>  > > > >
>  > > > >                 public BrandValueEncoder(List<Brand> brands) {
>  > > > >                         this.brands = brands;
>  > > > >                 }
>  > > > >
>  > > > >                 public String toClient(Brand brand) {
>  > > > >                         return brand.getDescription();
>  > > > >                 }
>  > > > >
>  > > > >                 public Brand toValue(String string) {
>  > > > >                         for(Brand brand : brands) {
>  > > > >
>  > > > > if(brand.getDescription().equals(string)) {
>  > > > >                                         return brand;
>  > > > >                                 }
>  > > > >                         }
>  > > > >                         return null;
>  > > > >                 }
>  > > > >
>  > > > >         }
>  > > > >
>  > > > >         public class BrandSelectModel implements SelectModel {
>  > > > >
>  > > > >                 private List<Brand> brands;
>  > > > >
>  > > > >                 public BrandSelectModel(List<Brand> brands) {
>  > > > >                         this.brands = brands;
>  > > > >                 }
>  > > > >
>  > > > >                 public List<OptionGroupModel> getOptionGroups() {
>  > > > >                         return null;
>  > > > >                 }
>  > > > >
>  > > > >                 public List<OptionModel> getOptions() {
>  > > > >                         List<OptionModel> optionModelList =
>  > > > >                                 new ArrayList<OptionModel>();
>  > > > >                         for(Brand brand: brands) {
>  > > > >                                 optionModelList.add(
>  > > > >                                   new OptionModelImpl(
>  > > > >                                         brand.getDescription(),
>  > > > >                                         false,
>  > > > >                                         brand,
>  > > > >                                         new String[0]
>  > > > >                                   )
>  > > > >                                 );
>  > > > >                         }
>  > > > >                         return optionModelList;
>  > > > >                 }
>  > > > >
>  > > > >         }
>  > > > >
>  > > > > }
>  > > > >
>  > > > >
>  > > > >
>  > > > > -----Original Message-----
>  > > > > From: Howard Lewis Ship [mailto:[EMAIL PROTECTED]
>  > > > > Sent: Saturday, May 05, 2007 9:45 PM
>  > > > > To: Tapestry users
>  > > > > Subject: Re: T5: SelectModel - a real world example
>  > > > >
>  > > > > What annotations are on the brand field of your Main class?  
> Something
>  > > >
>  > > > > has changes that field to be read-only, which is usually a sign that 
> a
>  > > >
>  > > > > value was injected.
>  > > > >
>  > > > > On 5/4/07, Joel Wiegman <[EMAIL PROTECTED]> wrote:
>  > > > > >
>  > > > > > Still getting unintuitive errors... I've added the ValueEncoder and
>  > > > > > now when I submit the form I get the following stack trace (and yes
>  > > > > > the "Main" component has a setBrand(Brand) method, which from the
>  > > > > > root
>  > > > >
>  > > > > > cause exception seems to be the cause of the problem?):
>  > > > > >
>  > > > > > [ERROR] RequestExceptionHandler Processing of request failed with
>  > > > > > uncaught exception:
>  > > > > > org.apache.tapestry.ioc.internal.util.TapestryException: Failure
>  > > > > > writing parameter value of component com.foo.pages.Main:brand: 
> Field
>  > > >
>  > > > > > com.foo.pages.Main.brand is read-only. [at
>  > > > > > context:WEB-INF/Main.html, line 89, column 278]
>  > > > > > java.lang.RuntimeException:
>  > > > > > org.apache.tapestry.ioc.internal.util.TapestryException: Failure
>  > > > > > writing parameter value of component com.foo.
>  > > > > > pages.Main:brand: Field com.foo.pages.Main.brand is read-only. [at
>  > > > > > context:WEB-INF/Main.html, line 89, column 278]
>  > > > > >         at
>  > > > > > org.apache.tapestry.corelib.components.Form.onAction(Form.java:356)
>  > > > > >         at
>  > > > > >
>  > > > org.apache.tapestry.corelib.components.Form.handleComponentEvent(Form.
>  > > > > > ja
>  > > > > > va)
>  > > > > >         at
>  > > > > > 
> org.apache.tapestry.internal.structure.ComponentPageElementImpl.hand
>  > > > > > le
>  > > > > > Ev
>  > > > > > ent(ComponentPageElementImpl.java:903)
>  > > > > >         at
>  > > > > > 
> org.apache.tapestry.internal.structure.ComponentPageElementImpl.trig
>  > > > > > ge
>  > > > > > rE
>  > > > > > vent(ComponentPageElementImpl.java:1002)
>  > > > > >         at
>  > > > > > 
> org.apache.tapestry.internal.services.ActionLinkHandlerImpl.handle(A
>  > > > > > ct
>  > > > > > io
>  > > > > > nLinkHandlerImpl.java:100)
>  > > > > >         at
>  > > > > > 
> org.apache.tapestry.internal.services.ActionLinkHandlerImpl.handle(A
>  > > > > > ct
>  > > > > > io
>  > > > > > nLinkHandlerImpl.java:53)
>  > > > > >         at
>  > > > > > 
> $ActionLinkHandler_11258c2d07d.handle($ActionLinkHandler_11258c2d07d
>  > > > > > .j
>  > > > > > av
>  > > > > > a)
>  > > > > >         at
>  > > > > > 
> org.apache.tapestry.internal.services.ComponentActionDispatcher.disp
>  > > > > > at
>  > > > > > ch
>  > > > > > (ComponentActionDispatcher.java:115)
>  > > > > >         ... 40 more
>  > > > > > Caused by: org.apache.tapestry.ioc.internal.util.TapestryException:
>  > > > > > Failure writing parameter value of component
>  > > > com.foo.pages.Main:brand:
>  > > > > > Field com.foo.pages.Main.brand is read-only. [at
>  > > > > > context:WEB-INF/Main.html, line 89, column 278]
>  > > > > >         at
>  > > > > >
>  > > > org.apache.tapestry.internal.structure.InternalComponentResourcesImpl.
>  > > > > > wr
>  > > > > > iteParameter(InternalComponentResourcesImpl.java:223)
>  > > > > >         at
>  > > > > > 
> org.apache.tapestry.corelib.components.Select._$update_parameter_val
>  > > > > > ue
>  > > > > > _0
>  > > > > > (Select.java)
>  > > > > >         at
>  > > > > > 
> org.apache.tapestry.corelib.components.Select.processSubmission(Sele
>  > > > > > ct
>  > > > > > .j
>  > > > > > ava:238)
>  > > > > >         at
>  > > > > > 
> org.apache.tapestry.corelib.base.AbstractField.processSubmission(Abs
>  > > > > > tr
>  > > > > > ac
>  > > > > > tField.java:210)
>  > > > > >         at
>  > > > > >
>  > > > >
>  > > > 
> org.apache.tapestry.corelib.base.AbstractField.access$100(AbstractField.
>  > > > > > java:47)
>  > > > > >         at
>  > > > > > 
> org.apache.tapestry.corelib.base.AbstractField$ProcessSubmissionActi
>  > > > > > on
>  > > > > > .e
>  > > > > > xecute(AbstractField.java:116)
>  > > > > >         at
>  > > > > > 
> org.apache.tapestry.corelib.base.AbstractField$ProcessSubmissionActi
>  > > > > > on
>  > > > > > .e
>  > > > > > xecute(AbstractField.java:110)
>  > > > > >         at
>  > > > > > org.apache.tapestry.corelib.components.Form.onAction(Form.java:347)
>  > > > > >         ... 40 more
>  > > > > > Caused by: org.apache.tapestry.ioc.internal.util.TapestryException:
>  > > > > > Field com.foo.pages.Main.brand is read-only. [at
>  > > > context:WEB-INF/Main.
>  > > > > > html, line 89, column 278]
>  > > > > >         at
>  > > > > > 
> org.apache.tapestry.internal.bindings.PropBinding.set(PropBinding.ja
>  > > > > > va
>  > > > > > :7
>  > > > > > 1)
>  > > > > >         at
>  > > > > >
>  > > > org.apache.tapestry.internal.structure.InternalComponentResourcesImpl.
>  > > > > > wr
>  > > > > > iteParameter(InternalComponentResourcesImpl.java:219)
>  > > > > >         ... 47 more
>  > > > > > Caused by: java.lang.RuntimeException: Field
>  > > > > > com.foo.pages.Main.brand is read-only.
>  > > > > >         at com.foo.pages.Main._$write_brand(Main.java)
>  > > > > >         at com.foo.pages.Main.setBrand(Main.java:92)
>  > > > > >         at
>  > > > > > $PropertyConduit_11258c2d0a9.set($PropertyConduit_11258c2d0a9.java)
>  > > > > >         at
>  > > > > > 
> org.apache.tapestry.internal.bindings.PropBinding.set(PropBinding.ja
>  > > > > > va
>  > > > > > :6
>  > > > > > 7)
>  > > > > >         ... 48 more
>  > > > > >
>  > > > > >
>  > > > > >
>  > > > > > -----Original Message-----
>  > > > > > From: Howard Lewis Ship [mailto:[EMAIL PROTECTED]
>  > > > > > Sent: Friday, May 04, 2007 2:32 PM
>  > > > > > To: Tapestry users
>  > > > > > Subject: Re: T5: SelectModel - a real world example
>  > > > > >
>  > > > > > In your OptionModel, the label is the Brand description, and the
>  > > > > > value
>  > > > >
>  > > > > > is the Brand itself.
>  > > > > >
>  > > > > > You then supply a ValueEncoder that converts between Brands and
>  > > > > > brand ids (as strings, for the client side). If Brand is an entity
>  > > > > > object, then it may be necessary to have the ValueEncoder talk to
>  > > > > > the database
>  > > > >
>  > > > > > or session store.
>  > > > > >
>  > > > > > On 5/4/07, Joel Wiegman <[EMAIL PROTECTED]> wrote:
>  > > > > > >
>  > > > > > > Thanks for the reply Howard.
>  > > > > > >
>  > > > > > > >> The Select component doesn't know how to create a client-side
>  > > > > > > representation of a Brand (it doesn't magically know to use the
>  > > > id).
>  > > > > > >
>  > > > > > > So, then... I guess my question would be... what is the
>  > > > > > > BrandSelectModel for?  In that object, I'm essentially mapping a
>  > > > > > > Brand's "description" to the Brand object.
>  > > > > > >
>  > > > > > > Just curious what your thoughts are on that...
>  > > > > > >
>  > > > > > >
>  > > > > > > -----Original Message-----
>  > > > > > > From: Howard Lewis Ship [mailto:[EMAIL PROTECTED]
>  > > > > > > Sent: Friday, May 04, 2007 1:42 PM
>  > > > > > > To: Tapestry users
>  > > > > > > Subject: Re: T5: SelectModel - a real world example
>  > > > > > >
>  > > > > > > In the simplest case, T5 thinks that the options in the drop down
>  > > > > > > list
>  > > > > >
>  > > > > > > are all strings.
>  > > > > > >
>  > > > > > > In your case, they are Brands.  The Select component doesn't know
>  > > > > > > how to create a client-side representation of a Brand (it doesn't
>  > > > > > > magically know to use the id).
>  > > > > > >
>  > > > > > > You must provide a ValueEncoder that can convert between Brands
>  > > > > > > and client-side string values.  This is the encoder parameter of
>  > > > > > > the Select component.
>  > > > > > >
>  > > > > > >
>  > > > > > > On 5/4/07, Joel Wiegman <[EMAIL PROTECTED]> wrote:
>  > > > > > > >
>  > > > > > > > Not to be harsh, but I don't think I've ever written a select
>  > > > > > > > box with
>  > > > > > >
>  > > > > > > > constant values (Enum).  Seems like even Male/Female drop downs
>  > > > > > > > need
>  > > > > >
>  > > > > > > > to be data-driven now-a-days.  :->
>  > > > > > > >
>  > > > > > > > I've started to stub out a very simple "real world example" of 
> a
>  > > >
>  > > > > > > > select component in T5, but it doesn't appear to be as simple 
> as
>  > > >
>  > > > > > > > I
>  > > > >
>  > > > > > > > thought it would be.
>  > > > > > > >
>  > > > > > > > A shiny nickel to anyone that can spot the flaw, because I sure
>  > > > > > > can't...
>  > > > > > > > I'm new to Tapestry in general so I could be missing something
>  > > > > > > > really mundane here, but seems like it should work in my mind.
>  > > > > > > >
>  > > > > > > > Here are the players:
>  > > > > > > >
>  > > > > > > > << THE ERROR >>
>  > > > > > > >
>  > > > > > > > [ERROR] DefaultRequestExceptionHandler Processing of request
>  > > > > > > > failed with uncaught exception: com.foo.data.Brand cannot be
>  > > > > > > > cast to java.lang.String
>  > > > > > > > java.lang.ClassCastException: com.foo.data.Brand cannot be cast
>  > > > > > > > to
>  > > > >
>  > > > > > > > java.lang.String
>  > > > > > > >         at
>  > > > > > > >
>  > > > > > > 
> org.apache.tapestry.corelib.components.Select$1.toClient(Select.ja
>  > > > > > > va
>  > > > > > > :6
>  > > > > > > 2)
>  > > > > > > >         at
>  > > > > > > >
>  > > > org.apache.tapestry.corelib.components.Select.writeOptions(Select.
>  > > > > > > > ja
>  > > > > > > > va
>  > > > > > > > :1
>  > > > > > > > 94)
>  > > > > > > >         at
>  > > > > > > >
>  > > > > > 
> org.apache.tapestry.corelib.components.Select.options(Select.java:16
>  > > > > > 9)
>  > > > > > > >         at
>  > > > > > > > 
> org.apache.tapestry.corelib.components.Select.beforeRenderTempla
>  > > > > > > > te
>  > > > > > > > (S
>  > > > > > > > el
>  > > > > > > > ec
>  > > > > > > > t.java)
>  > > > > > > >
>  > > > > > > >
>  > > > > > > > << Main.html (abridged) >>
>  > > > > > > >
>  > > > > > > > <t:form>
>  > > > > > > >         <select t:type="select" t:id="brand" value="brand"
>  > > > > > > > model="brandSelectModel"/>
>  > > > > > > > </t:form>
>  > > > > > > >
>  > > > > > > >
>  > > > > > > > << Main.java (abridged) >>
>  > > > > > > >
>  > > > > > > > package com.foo.pages;
>  > > > > > > >
>  > > > > > > > import com.foo.data.Brand;
>  > > > > > > >
>  > > > > > > > public class Main {
>  > > > > > > >
>  > > > > > > >         private Brand brand;
>  > > > > > > >
>  > > > > > > >         public Brand getBrand() {
>  > > > > > > >                 return brand;
>  > > > > > > >         }
>  > > > > > > >
>  > > > > > > >         public void setBrand(Brand brand) {
>  > > > > > > >                 this.brand = brand;
>  > > > > > > >         }
>  > > > > > > >
>  > > > > > > >         public BrandSelectModel getBrandSelectModel() {
>  > > > > > > >                 return new BrandSelectModel(getBrands());
>  > > > > > > >         }
>  > > > > > > >
>  > > > > > > >         public List<Brand> getBrands() {
>  > > > > > > >                 List<Brand> brands = new ArrayList<Brand>();
>  > > > > > > >                 brands.add(new Brand("1", "Brand 1"));
>  > > > > > > >                 brands.add(new Brand("2", "Brand 2"));
>  > > > > > > >                 brands.add(new Brand("3", "Brand 3"));
>  > > > > > > >                 return brands;
>  > > > > > > >         }
>  > > > > > > >
>  > > > > > > > }
>  > > > > > > >
>  > > > > > > >
>  > > > > > > > << Brand.java (abridged) >>
>  > > > > > > >
>  > > > > > > > package com.foo.data;
>  > > > > > > >
>  > > > > > > > public class Brand {
>  > > > > > > >
>  > > > > > > >         private String id;
>  > > > > > > >         private String description;
>  > > > > > > >
>  > > > > > > >         public Brand() {}
>  > > > > > > >
>  > > > > > > >         public Brand(String id, String description) {
>  > > > > > > >                 this.id = id;
>  > > > > > > >                 this.description = description;
>  > > > > > > >         }
>  > > > > > > >
>  > > > > > > >         public String getId() {
>  > > > > > > >                 return id;
>  > > > > > > >         }
>  > > > > > > >
>  > > > > > > >         public String getDescription() {
>  > > > > > > >                 return description;
>  > > > > > > >         }
>  > > > > > > >
>  > > > > > > > }
>  > > > > > > >
>  > > > > > > >
>  > > > > > > > << BrandSelectModel.java >>
>  > > > > > > >
>  > > > > > > > package com.foo.uisupport;
>  > > > > > > >
>  > > > > > > > import com.foo.data.Brand;
>  > > > > > > >
>  > > > > > > > public class BrandSelectModel implements SelectModel {
>  > > > > > > >
>  > > > > > > >         private List<Brand> brands;
>  > > > > > > >
>  > > > > > > >         public BrandSelectModel(List<Brand> brands) {
>  > > > > > > >                 this.brands = brands;
>  > > > > > > >         }
>  > > > > > > >
>  > > > > > > >         public List<OptionGroupModel> getOptionGroups() {
>  > > > > > > >                 return null;
>  > > > > > > >         }
>  > > > > > > >
>  > > > > > > >         public List<OptionModel> getOptions() {
>  > > > > > > >                 List<OptionModel> optionModelList = new
>  > > > > > > > ArrayList<OptionModel>();
>  > > > > > > >                 for(Brand brand: brands) {
>  > > > > > > >                         optionModelList.add(new
>  > > > > > > > OptionModelImpl(brand.getDescription(), false, brand, new
>  > > > > > String[0]));
>  > > > > > > >                 }
>  > > > > > > >                 return optionModelList;
>  > > > > > > >         }
>  > > > > > > >
>  > > > > > > > }
>  > > > > > > >
>  > > > > > > >
>  > > > > > > >
>  > > > > > > > 
> ----------------------------------------------------------------
>  > > > > > > > --
>  > > > > > > > --
>  > > > > > > > - To unsubscribe, e-mail: [EMAIL PROTECTED]
>  > > > > > > > For additional commands, e-mail: [EMAIL PROTECTED]
>  > > > > > > >
>  > > > > > > >
>  > > > > > >
>  > > > > > >
>  > > > > > > --
>  > > > > > > Howard M. Lewis Ship
>  > > > > > > TWD Consulting, Inc.
>  > > > > > > Independent J2EE / Open-Source Java Consultant Creator and PMC
>  > > > > > > Chair, Apache Tapestry Creator, Apache HiveMind
>  > > > > > >
>  > > > > > > Professional Tapestry training, mentoring, support and project
>  > > > work.
>  > > > > > > http://howardlewisship.com
>  > > > > > >
>  > > > > > > 
> ------------------------------------------------------------------
>  > > > > > > --
>  > > > > > > - To unsubscribe, e-mail: [EMAIL PROTECTED]
>  > > > > > > For additional commands, e-mail: [EMAIL PROTECTED]
>  > > > > > >
>  > > > > > >
>  > > > > >
>  > > > > >
>  > > > > > --
>  > > > > > Howard M. Lewis Ship
>  > > > > > TWD Consulting, Inc.
>  > > > > > Independent J2EE / Open-Source Java Consultant Creator and PMC
>  > > > > > Chair, Apache Tapestry Creator, Apache HiveMind
>  > > > > >
>  > > > > > Professional Tapestry training, mentoring, support and project 
> work.
>  > > > > > http://howardlewisship.com
>  > > > > >
>  > > > > > 
> --------------------------------------------------------------------
>  > > > > > - To unsubscribe, e-mail: [EMAIL PROTECTED]
>  > > > > > For additional commands, e-mail: [EMAIL PROTECTED]
>  > > > > >
>  > > > > >
>  > > > >
>  > > > >
>  > > > > --
>  > > > > Howard M. Lewis Ship
>  > > > > TWD Consulting, Inc.
>  > > > > Independent J2EE / Open-Source Java Consultant Creator and PMC Chair,
>  > > > > Apache Tapestry Creator, Apache HiveMind
>  > > > >
>  > > > > Professional Tapestry training, mentoring, support and project work.
>  > > > > http://howardlewisship.com
>  > > > >
>  > > > > ---------------------------------------------------------------------
>  > > > > To unsubscribe, e-mail: [EMAIL PROTECTED]
>  > > > > For additional commands, e-mail: [EMAIL PROTECTED]
>  > > > >
>  > > > >
>  > > >
>  > > >
>  > > > --
>  > > > Howard M. Lewis Ship
>  > > > TWD Consulting, Inc.
>  > > > Independent J2EE / Open-Source Java Consultant Creator and PMC Chair,
>  > > > Apache Tapestry Creator, Apache HiveMind
>  > > >
>  > > > Professional Tapestry training, mentoring, support and project work.
>  > > > http://howardlewisship.com
>  > > >
>  > > > ---------------------------------------------------------------------
>  > > > To unsubscribe, e-mail: [EMAIL PROTECTED]
>  > > > For additional commands, e-mail: [EMAIL PROTECTED]
>  > > >
>  > > >
>  > >
>  > >
>  > > --
>  > > "The future is here.  It's just not evenly distributed yet."
>  > >
>  > >      -- Traditional
>  > >
>  > > ---------------------------------------------------------------------
>  > > To unsubscribe, e-mail: [EMAIL PROTECTED]
>  > > For additional commands, e-mail: [EMAIL PROTECTED]
>  > >
>  > >
>  >
>  >
>  > --
>  > Howard M. Lewis Ship
>  > TWD Consulting, Inc.
>  > Independent J2EE / Open-Source Java Consultant
>  > Creator and PMC Chair, Apache Tapestry
>  > Creator, Apache HiveMind
>  >
>  > Professional Tapestry training, mentoring, support
>  > and project work.  http://howardlewisship.com
>  >
>
>
>  --
>
>
> "The future is here.  It's just not evenly distributed yet."
>
>      -- Traditional
>
>  ---------------------------------------------------------------------
>  To unsubscribe, e-mail: [EMAIL PROTECTED]
>  For additional commands, e-mail: [EMAIL PROTECTED]
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to