Re: T5: SelectModel - a real world example
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 ListBrand brands; public Brand getBrand() { return brand; } public void setBrand(Brand brand) { this.brand = brand; } private ListBrand getBrands() { if(brands == null) { brands = new ArrayListBrand(); 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 ValueEncoderBrand { private ListBrand brands; public BrandValueEncoder(ListBrand 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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
Re: T5: SelectModel - a real world example
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 ListBrand brands; public Brand getBrand() { return brand; } public void setBrand(Brand brand) { this.brand = brand; } private ListBrand getBrands() { if(brands == null) { brands = new ArrayListBrand(); 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 ValueEncoderBrand { private ListBrand brands; public BrandValueEncoder(ListBrand 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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
Re: T5: SelectModel - a real world example
-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 ValueEncoderBrand { private ListBrand brands; public BrandValueEncoder(ListBrand 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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
RE: T5: SelectModel - a real world example
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 ValueEncoderBrand { private ListBrand brands; public BrandValueEncoder(ListBrand 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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.handle Ev ent(ComponentPageElementImpl.java:903) at org.apache.tapestry.internal.structure.ComponentPageElementImpl.trigge rE vent
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 ValueEncoderBrand { private ListBrand brands; public BrandValueEncoder(ListBrand 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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.handle Ev ent(ComponentPageElementImpl.java:903
RE: T5: SelectModel - a real world example
Nope... Just using the standard Jetty/Maven desktop environment. I've created and attached a simple demo if you'd like to see the problem in action. Only three small files... the HTML page, the Java file, and the Brand POJO. You'll need to change the package of the Java files to fit your application, but shouldn't need to change much else... Otherwise, I guess I'll anxiously await an example of a binding select box! Thanks for all your help Howard! -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 ValueEncoderBrand { private ListBrand brands; public BrandValueEncoder(ListBrand 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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
RE: T5: SelectModel - a real world example
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 @Persisted 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 ListBrand brands; public Brand getBrand() { return brand; } public void setBrand(Brand brand) { this.brand = brand; } private ListBrand getBrands() { if(brands == null) { brands = new ArrayListBrand(); 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 ValueEncoderBrand { private ListBrand brands; public BrandValueEncoder(ListBrand 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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
Re: T5: SelectModel - a real world example
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 @Persisted 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 ListBrand brands; public Brand getBrand() { return brand; } public void setBrand(Brand brand) { this.brand = brand; } private ListBrand getBrands() { if(brands == null) { brands = new ArrayListBrand(); 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 ValueEncoderBrand { private ListBrand brands; public BrandValueEncoder(ListBrand 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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
Re: T5: SelectModel - a real world example
( 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 ValueEncoderBrand { private ListBrand brands; public BrandValueEncoder(ListBrand 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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
Re: T5: SelectModel - a real world example
() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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 ValueEncoderBrand { private ListBrand brands; public BrandValueEncoder(ListBrand 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); for(Brand brand: brands) { optionModelList.add( new OptionModelImpl( brand.getDescription(), false, brand, new String[0
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.handleEv ent(ComponentPageElementImpl.java:903) at org.apache.tapestry.internal.structure.ComponentPageElementImpl.triggerE vent(ComponentPageElementImpl.java:1002) at org.apache.tapestry.internal.services.ActionLinkHandlerImpl.handle(Actio nLinkHandlerImpl.java:100) at org.apache.tapestry.internal.services.ActionLinkHandlerImpl.handle(Actio nLinkHandlerImpl.java:53) at $ActionLinkHandler_11258c2d07d.handle($ActionLinkHandler_11258c2d07d.jav a) at org.apache.tapestry.internal.services.ComponentActionDispatcher.dispatch (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_value_0 (Select.java) at org.apache.tapestry.corelib.components.Select.processSubmission(Select.j ava:238) at org.apache.tapestry.corelib.base.AbstractField.processSubmission(Abstrac tField.java:210) at org.apache.tapestry.corelib.base.AbstractField.access$100(AbstractField. java:47) at org.apache.tapestry.corelib.base.AbstractField$ProcessSubmissionAction.e xecute(AbstractField.java:116) at org.apache.tapestry.corelib.base.AbstractField$ProcessSubmissionAction.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.java: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.java: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
T5: SelectModel - a real world example
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.java:62) at org.apache.tapestry.corelib.components.Select.writeOptions(Select.java:1 94) at org.apache.tapestry.corelib.components.Select.options(Select.java:169) at org.apache.tapestry.corelib.components.Select.beforeRenderTemplate(Selec 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 ListBrand getBrands() { ListBrand brands = new ArrayListBrand(); 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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]
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.java:62) at org.apache.tapestry.corelib.components.Select.writeOptions(Select.java:1 94) at org.apache.tapestry.corelib.components.Select.options(Select.java:169) at org.apache.tapestry.corelib.components.Select.beforeRenderTemplate(Selec 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 ListBrand getBrands() { ListBrand brands = new ArrayListBrand(); 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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
RE: T5: SelectModel - a real world example
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.java:62) at org.apache.tapestry.corelib.components.Select.writeOptions(Select.java :1 94) at org.apache.tapestry.corelib.components.Select.options(Select.java:169) at org.apache.tapestry.corelib.components.Select.beforeRenderTemplate(Sel 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 ListBrand getBrands() { ListBrand brands = new ArrayListBrand(); 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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]
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.java:62) at org.apache.tapestry.corelib.components.Select.writeOptions(Select.java :1 94) at org.apache.tapestry.corelib.components.Select.options(Select.java:169) at org.apache.tapestry.corelib.components.Select.beforeRenderTemplate(Sel 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 ListBrand getBrands() { ListBrand brands = new ArrayListBrand(); 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 ListBrand brands; public BrandSelectModel(ListBrand brands) { this.brands = brands; } public ListOptionGroupModel getOptionGroups() { return null; } public ListOptionModel getOptions() { ListOptionModel optionModelList = new ArrayListOptionModel(); 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
RE: T5: SelectModel - a real world example
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.handleEv ent(ComponentPageElementImpl.java:903) at org.apache.tapestry.internal.structure.ComponentPageElementImpl.triggerE vent(ComponentPageElementImpl.java:1002) at org.apache.tapestry.internal.services.ActionLinkHandlerImpl.handle(Actio nLinkHandlerImpl.java:100) at org.apache.tapestry.internal.services.ActionLinkHandlerImpl.handle(Actio nLinkHandlerImpl.java:53) at $ActionLinkHandler_11258c2d07d.handle($ActionLinkHandler_11258c2d07d.jav a) at org.apache.tapestry.internal.services.ComponentActionDispatcher.dispatch (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_value_0 (Select.java) at org.apache.tapestry.corelib.components.Select.processSubmission(Select.j ava:238) at org.apache.tapestry.corelib.base.AbstractField.processSubmission(Abstrac tField.java:210) at org.apache.tapestry.corelib.base.AbstractField.access$100(AbstractField. java:47) at org.apache.tapestry.corelib.base.AbstractField$ProcessSubmissionAction.e xecute(AbstractField.java:116) at org.apache.tapestry.corelib.base.AbstractField$ProcessSubmissionAction.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.java: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.java: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