Using the BeanEditForm Component
Tapestry includes BeanEditForm is a powerful Tapestry component capable of generating a complete create/edit user interface for a typical JavaBean, BeanEditForm..
Div |
---|
style | float: right; max-width: 30%; margin: 1em |
---|
|
Panel |
---|
borderColor | #eee |
---|
titleBGColor | #eee |
---|
title | JumpStart Demos |
---|
| |
|
BeanEditForm analyzes the the properties of the bean, locating just those properties that are readable and writablewriteable. It filters down to properties whose type is mapped to a known editor (this is described in more detail below).
...
For example, you may want to selectively use a PasswordField component:
Code Block |
---|
|
<t:beaneditform object="loginCredentials">
<p:password>
<t:label for="password"/>
<t:passwordfield t:id="password" value="loginCredentials.password"/>
</p:password>
</t:beaneditform>
|
...
The model can be created when the page is first instantiated:
Code Block |
---|
|
public class MyPage
{
@Inject
private BeanModelSource beanModelSource;
@Inject
private ComponentResources resources;
@Property(write=false)
@Retain
private BeanModel model;
@Property
private MyBean bean;
{
model = beanModelSource.create(MyBean.class, true, resources);
// Make other changes to model here.
}
}
|
And, in the component template, the built model can be passed to the BeanEditForm component explicitly:
Code Block |
---|
|
<t:beaneditform object="bean" model="model"/>
|
...
Next, you must make contributions to the DataTypeAnalyzer or DefaultDataTypeAnalyzer services to match properties to your new name.
DataTypeAnalyzer is a chain of command that can match properties to data types based on property type or annotations on the property. In general, DefaultDataTypeAnalyzer is used, as that only needs to consider property type. DefaultDataTypeAnalyzer matches property types to data types, based on a search up the inheritance path.
Code Block |
---|
|
public static void contributeDefaultDataTypeAnalyzer(MappedConfiguration<Class, String> configuration)
{
configuration.add(BigDecimal.class, "currency");
}
|
You must provide an editor for the "currency" data type. An editor is a block of a page of the application; this page is not normally rendered itself, but acts as a container for one or more blocks.
Code Block |
---|
|
public class AppPropertyEditBlocks
{
@Property
@Environmental
private PropertyEditContext context;
@Component(parameters =
{ "value=context.propertyValue", "label=prop:context.label",
"translate=prop:currencyTranslator", "validate=prop:currencyValidator",
"clientId=prop:context.propertyId", "annotationProvider=context" })
private TextField currency;
@Inject
private ComponentResources resources;
public FieldValidator getCurrencyValidator()
{
return context.getValidator(currency);
}
public FieldTranslator getCurrencyTranslator()
{
return context.getTranslator(current);
}
}
|
...
The editor is a block inside the component template:
Code Block |
---|
|
<t:block id="currency">
<t:label for="currency"/>
<t:textfield t:id="currency" size="10"/>
</t:block>
|
Finally, we tell the BeanEditForm component about the editor via a contribution to the BeanBlockSource service:
Code Block |
---|
|
public static void contributeBeanBlockSource(Configuration<BeanBlockContribution> configuration)
{
configuration.add(new BeanBlockContribution("currency", "AppPropertyEditBlocks", "currency", true));
}
|
...