Excerpt |
---|
|
Using SelectModel, SelectModelFactory and ValueEncoder for Select menus populated from a database |
Using Select With a List
The documentation for the Select Component and the Tapestry Tutorial provide simplistic examples of populating a drop-down menu (as the (X)HTML Select element) using comma-delimited strings and enums. However, most real-world Tapestry applications need to populate such menus using values from a database, commonly in the form of java.util.List objects. Doing so generally requires a SelectModel and a ValueEncoder bound to the Select component with its "model" and "encoder" parameters:
Code Block |
---|
<t:select t:id="colorMenu" value="selectedColor" model="ColorSelectModel" encoder="colorEncoder" />
|
In the above example, ColorSelectModel must be of type SelectModel, or anything that Tapestry knows how to coerce into a SelectModel, such as a List or a Map or a "value=label,value=label,..." delimited string, or anything Tapestry knows how to coerce into a List or Map, such as an Array or a comma-delimited String.
SelectModel
Wiki Markup |
---|
{float:right|background=#eee|padding=0 1em}
*JumpStart Demo:*
[Total Control Object Select|http://jumpstart.doublenegative.com.au/jumpstart/examples/select/totalcontrolobject]
[ID Select|http://jumpstart.doublenegative.com.au/jumpstart/examples/select/id]
[Easy ID Selet|http://jumpstart.doublenegative.com.au/jumpstart/examples/select/easyid]
{float} |
A SelectModel is a collection of options (specifically OptionModel objects) for a drop-down menu. Basically, each option is a value (an object) and a label (presented to the user).
...
Code Block |
---|
title | SelectWithListDemo.java (a page class) |
---|
|
@Property
private SelectModel colorSelectModel;
@Inject
SelectModelFactory selectModelFactory;
...
void setupRender() {
// invoke my service to find all colors, e.g. in the database
List<Color> colors = colorService.findAll();
// create a SelectModel from my list of colors
colorSelectModel = selectModelFactory.create(colors, "name");
}
|
...
Code Block |
---|
title | Color.java (partial) |
---|
|
...
@Override
public String toString() {
return String.valueOf(this.getId());
}
|
...
Code Block |
---|
title | ColorEncoder.java (perhaps in your com.example.myappname.encoders package) |
---|
|
public class ColorEncoder implements ValueEncoder<Color>, ValueEncoderFactory<Color> {
@Inject
private ColorService colorService;
@Override
public String toClient(Color value) {
// return the given object's ID
return String.valueOf(value.getId());
}
@Override
public Color toValue(String id) {
// find the color object of the given ID in the database
return colorService.findById(Long.parseLong(id));
}
// let this ValueEncoder also serve as a ValueEncoderFactory
@Override
public ValueEncoder<Color> create(Class<Color> type) {
return this;
}
}
|
...
Code Block |
---|
title | SelectWithListDemo.java (a page class, partial) |
---|
|
. . .
public ValueEncoder<Color> getColorEncoder() {
return new ValueEncoder<Color>() {
@Override
public String toClient(Color value) {
// return the given object's ID
return String.valueOf(value.getId());
}
@Override
public Color toValue(String id) {
// find the color object of the given ID in the database
return colorService.findById(Long.parseLong(id));
}
};
}
|
...
Code Block |
---|
title | AppModule.java (partial) |
---|
|
...
public static void contributeValueEncoderSource(MappedConfiguration<Class<Color>,
ValueEncoderFactory<Color>> configuration) {
configuration.addInstance(Color.class, ColorEncoder.class);
}
|
...
Code Block |
---|
title | AppModule.java (partial) |
---|
|
...
public static void contributeValueEncoderSource(MappedConfiguration<Class,
ValueEncoderFactory> configuration)
{
configuration.addInstance(Color.class, ColorEncoder.class);
configuration.addInstance(SomeOtherType.class, SomeOtherTypeEncoder.class);
}
|
...
Code Block |
---|
title | SelectWithListDemo.tml (partial) |
---|
|
<t:select t:id="colorMenu" value="selectedColorId" model="ColorSelectModel" />
|
Code Block |
---|
title | SelectWithListDemo.java (partial) |
---|
|
...
public void onSuccessFromMyForm() {
// look up the color object from the ID selected
selectedColor = colorService.findById(selectedColorId);
...
}
|
...