我正在尝试生成一个带有变量的表单 - 在服务器端 - 文本字段的数量。 tapestry页面看起来类似于:
<form t:id="form">
<t:loop source="typesOfIncome" value="typeOfIncome">
<input t:type="TextField" t:id="typeOfIncome-${typeOfIncome.propertyIndex}" value="100"/>
</t:loop>
</form>
Tapestry不接受这一点,因为它摒弃了
组件ID'typeOfIncome - $ {typeOfIncome.propertyIndex}'无效;组件ID必须是有效的Java标识符:以字母开头,由字母,数字和下划线组成。
如何使用Tapestry实现这一目标? Java代码在组件中的外观如何?
更新:
使用类似的组件:
public class FormSample {
@Component
private Form _form;
@Inject
private Logger _log;
@Property
private List<String> _typesOfIncome;
@Property
private String _typeOfIncome;
@SetupRender
void setupRender() {
_typesOfIncome = Arrays.asList("First", "Second");
}
void onSuccess() {
_log.info("Got values " + _typesOfIncome + " .");
}
}
和包含
的页面<form t:id="form">
<t:loop source="typesOfIncome" value="typeOfIncome">
<input t:type="TextField" t:id="typeOfIncome" t:value="typeOfIncome"/> <br/>
</t:loop>
<input type="submit" value="Save"/>
</form>
在onSuccess
中,值列表为空。值为POST:
typeOfIncome First
typeOfIncome_0 Second
答案 0 :(得分:2)
我做了一些测试并更新了这个。你可以用纯粹的List来做到这一点,但我只能使用一个类来保持收入类型。
在Java中:
@Property
@Persist
private List<Info> _infoList;
@Property
private Info _info;
void onPrepare() {
// populate _typesOfIncome with existing ones
if (_infoList == null) {
_infoList = new ArrayList<Info>();
_infoList.add(new Info("type1"));
_infoList.add(new Info("type2"));
}
}
void onSuccess() {
for (Info i : _infoList) {
System.out.println(i.getTypeOfIncome());
}
}
public class Info {
private String typeOfIncome;
public Info() { }
public Info(String typeOfIncome) {
this.typeOfIncome = typeOfIncome;
}
public String getTypeOfIncome() {
return typeOfIncome;
}
public void setTypeOfIncome(String typeOfIncome) {
this.typeOfIncome = typeOfIncome;
}
}
在模板中:
<t:form t:id="form">
<t:loop t:source="infoList" t:value="info" formState="ITERATION">
<input t:type="TextField" t:id="typeOfIncome" t:value="info.typeOfIncome"/><br/>
</t:loop>
<input t:type="submit" name="Submit"/>
</t:form>
如果您希望能够动态添加新类型here's a good example。