创建动态html表单

时间:2012-10-20 00:01:34

标签: playframework playframework-2.0

尝试学习如何创建动态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

不确定在回发后捕获数据的正确方法

1 个答案:

答案 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
}