Dear Wiki user, You have subscribed to a wiki page or wiki category on "Tapestry Wiki" for change notification.
The following page has been changed by DavorHrg: http://wiki.apache.org/tapestry/Tapestry5HowtoSelectWithObjects New page: Creating a <SELECT> is a bit complicated and there is only support for strings and enums currently. (T5.0.5) Tapestry Select uses: * !SelectModel to get groups and options, and it is responsible for displayed text (<option value=..>TEXT</option>) * !ValueEncoder to generate value parameter for <option> tag and restore the selected value back after form is submitted Eums and strings are ok, but many people will want to use Objects (Beans, POJO-s from database via ORM). This has proven to be a dificult task, especialy since we are all new to T5. Here is an example of a !SelectionModel that simplifies using Select component with objects. It requires 5 parameters * List<T> - the list of objects that can be selected * Class<T> - Superclass of all objects in the list (this is because of Generics deletion at runtime) so an adapter can be produced (even byte code generated one might be implemented in Tapestry-ioc later on) * name of the identifier property - a property that identifies the object (usualy id if object is from database), it will be used as value attribute for the <option> * name of the name property - if name is composed of few properties, add an transient property to your Object * PropertyAccess - this is an Tapestry-ioc service that the selection model uses to access properties from the object and you must supply it. You can get inject it into your page easily {{{ @Inject PropertyAccess _access; }}} Another catch is that Value encoder needs the original list to recreate the object later after form is submitted. So we implement ValueEncoder interface directly in our !SelectModel implementation, and supply the model both as model and encoder parameter of Select component. {{{ <t:select model="myModel" encoder="myModel" value="someBean"/> }}} [[BR]] Here's code for the !SelecModel implementation: !GenericSelectModel {{{ import java.util.ArrayList; import java.util.List; import org.apache.tapestry.OptionGroupModel; import org.apache.tapestry.OptionModel; import org.apache.tapestry.ValueEncoder; import org.apache.tapestry.internal.OptionModelImpl; import org.apache.tapestry.ioc.services.PropertyAccess; import org.apache.tapestry.ioc.services.PropertyAdapter; import org.apache.tapestry.util.AbstractSelectModel; /** Generic selection model for a list of Objects. * use: * <pre>@Inject private PropertyAccess _access;</pre> * in your page to ge the [EMAIL PROTECTED] PropertyAccess} service.<br> * !Notice: you must set the created instance both as model and encoder parameter for the [EMAIL PROTECTED] Select} component.*/ public class GenericSelectModel<T> extends AbstractSelectModel implements ValueEncoder<T> { private PropertyAdapter labelFieldAdapter; private PropertyAdapter idFieldAdapter; private List<T> list; public GenericSelectModel(List<T> list, Class<T> clazz, String labelField, String idField, PropertyAccess access) { this.list = list; if (idField != null) this.idFieldAdapter = access.getAdapter(clazz).getPropertyAdapter(idField); if (labelField != null) this.labelFieldAdapter = access.getAdapter(clazz).getPropertyAdapter(labelField); } public List<OptionGroupModel> getOptionGroups() { return null; } public List<OptionModel> getOptions() { List<OptionModel> optionModelList = new ArrayList<OptionModel>(); if (labelFieldAdapter == null) { for (T obj : list) { optionModelList.add(new OptionModelImpl(nvl(obj), false, obj, new String[0])); } } else { for (T obj : list) { optionModelList.add(new OptionModelImpl(nvl(labelFieldAdapter.get(obj)), false, obj, new String[0])); } } return optionModelList; } // ValueEncoder functions public String toClient(T obj) { if (idFieldAdapter == null) { return obj + ""; } else { return idFieldAdapter.get(obj) + ""; } } public T toValue(String string) { if (idFieldAdapter == null) { for (T obj : list) { if (nvl(obj).equals(string)) return obj; } } else { for (T obj : list) { if (nvl(idFieldAdapter.get(obj)).equals(string)) return obj; } } return null; } private String nvl(Object o) { if (o == null) return ""; else return o.toString(); } } }}} [[BR]] here's an example Bean {{{ public class SomeBean { Long id; String name; public SomeBean(Long id, String name) { this.id = id; this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } }}} [[BR]] Example page class {{{ public class SelectTest { @Persist private SomeBean _someBean; @Inject private PropertyAccess _access; private GenericSelectModel<SomeBean> _beans; public SelectTest(){ ArrayList<SomeBean> list = new ArrayList<SomeBean>(); list.add(new SomeBean(1L,"Mirko")); list.add(new SomeBean(2L,"Slavko")); list.add(new SomeBean(3L,"Jozo")); _beans = new GenericSelectModel<SomeBean>(list,SomeBean.class,"name","id",_access); } public SomeBean getSomeBean(){ return _someBean; } public void setSomeBean(SomeBean _someBean){ this._someBean = _someBean; } public GenericSelectModel<SomeBean> getBeans(){ return _beans; } } }}} [[BR]] the test page: {{{ <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>Select test</title> </head> <body style="font-family:Courier new"> <form t:type="Form"> <t:select model="beans" encoder="beans" value="someBean"/> <t:submit/> </form> value: ${someBean} </body> </html> }}} --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
