尝试学习如何创建动态html表单。元素将在数据库中定义。创建页面后,控制器将处理回发数据,以将数据插入数据库。
我正在使用playframework 1.2.4
非常感谢任何指南/有用的链接
如果我知道元素是什么,我可以构建页面,当我从控制器调用render(param对象)并访问我视图中的对象时,可以从数据库表中提取数据以供选择列表。
我的黑客到目前为止: 创建了一个包含以下列的表
rid
HTMLElementType
ElementName
HTMLElementOptions [if the element type is select]
HTMLDefaultValue [default value for select like 'select a value from below']
HTMLElementEnabled
创建了一个模型
package models;
import play.*;
import play.db.jpa.*;
import play.data.validation.*;
import javax.persistence.*;
import java.util.*;
@javax.persistence.Entity
@Table(name="mytable")
public class DynameForm extends Model{
public String HTMLElementType;
public String ElementName;
public String HTMLElementOptions;
public String HTMLDefaultValue;
public String HTMLElementEnabled;
}
在我的视图中,我循环检查它是否为<select>
,如果是这样,则放入一个空选项。但不确定这是不是正确的方法。此外,在我看来,我还必须检查是否不是,然后我必须放入<input type=>
并构建完整的标签
此外,我如何对某些字段强制执行验证,如示例姓氏/ ssn / etc?我可以改变我的表,以获得一个可以帮助我的列IsRequire
不确定在回发后捕获数据的正确方法
答案 0 :(得分:2)
基本上问题是生成一个html表单。您似乎已经找到了您的模型。你缺少的是一个观点。我做了类似下面的事情,为simpleDB模型生成模型。
我提供了一个字段列表,并根据这些字段生成UI。我只有文本字段,只想要2个案例(可见和不可见)字段。您的用例可能需要更多复杂性,因此您可以根据需要进行调整。
dish.fields
包含具有相关元数据的字段。任何特殊的东西,如需要验证或isRequired,你必须向视图提供该信息,因此它可以以适当的方式呈现该字段。
最简单的建模方法是从HTML表单开始,然后开始一次将其概括为一个字段。
#{list items:dish.fields, as:'f'}
#{field 'f'}
#{if f.display }
<div class="control-group">
<label class="control-label"> &{f.name} </label>
<div class="controls">
<input type="text" class="input-xlarge" placeholder="&{f.name}" name="${dish.getFieldId(f)}" value="${dish.getValue(f)}" ></input>
</div>
</div>
#{/if}
#{else}
<input type="hidden" class="input-xlarge" placeholder="&{f.name}" name="${dish.getFieldId(f)}" value="${dish.getValue(f)}" ></input>
#{/else}
#{/field}
#{/list}
#{else}
No fields
#{/else}
我必须定义自己的字段,但你应该能够理解。
对于不同的用例,您可能必须拥有一堆不同的输入类型,因此请在开始时使用简单和概括。您也可以查看CRUD模块实现。
我的DisplayAttribute
类(字段的元数据)如下所示。您可以将它作为起点。
public class DisplayAttribute {
public Boolean display = Boolean.TRUE;
public String type = "";
public String name;
public DisplayAttribute(String name){
this.name = name;
this.display = Boolean.TRUE;
}
public DisplayAttribute(String name, Boolean display){
this.name = name;
this.display = display;
}
... overridden equals and hash
}
修改强>
如何渲染字段?
Controller将元数据(DisplayAttribute
)传递给视图,在这种情况下,元数据只包含字段的名称,而且可以显示或不显示。
<强>模型强>
此模型包含要渲染的字段,但您可以轻松地从数据库中检索这些字段。我的模型是通用的,因为我意识到我一直在为多个模型一遍又一遍地做同样的事情。
我实现了自己的界面,它提供了getFields
方法。我还维护了两个映射,因此给定一个属性,我可以得到它的DisplayAttribute,并给定一个DisplayAttribute我得到它的名字。我在需要时从视图中调用此模型的方法。
public class GenericSimpleDBModel implements SimpleDBModel {
public static AmazonSimpleDB sdb = null;
private static final String bracketRemovalPattern = "(^.*?\\[|\\]\\s*$)";
private Map<DisplayAttribute, Set<String>> data = new TreeMap<DisplayAttribute, Set<String>>(new UuidComparator());
private Map<String, DisplayAttribute> attributeCache = new HashMap<String, DisplayAttribute>();
protected final String DOMAIN_NAME;
public GenericSimpleDBModel() {
initialize(getFields());
this.DOMAIN_NAME = "dishes";
}
protected void initialize(String[] fields) {
data = new TreeMap<DisplayAttribute, Set<String>>(new UuidComparator());
attributeCache = new HashMap<String, DisplayAttribute>();
for (String f : fields) {
// if (f.equals(getUUIDField()) || f.equals(getIntegrityField())) {
if (f.endsWith("uuid") || f.endsWith("integrity")) {
setValue(f, "", Boolean.FALSE);
} else {
setValue(f, "", Boolean.TRUE);
}
}
}
protected void initialize(Set<DisplayAttribute> fields) {
data = new TreeMap<DisplayAttribute, Set<String>>(new UuidComparator());
attributeCache = new HashMap<String, DisplayAttribute>();
for (DisplayAttribute atr : fields) {
setValue(atr.name, "");
}
}
... more methods
}