0

使用 Play 2.3.7 (Java) 我有以下场景。

我有一个CSVData包含类型列表的类CSVField。以下是这些类的属性:

public class CSVData{

private String name;
private String description;
private String dataFilePath;
private List<CSVField> fields;
private Double latitude;
private Double longitude;


// rest of class... }

public class CSVField {
    private String name;
    private String type;

...}

制作表单输入时的困难CSVData在于我有这个嵌套List<CSVField>属性并且CSVField是包含两个字符串的自定义类型。我需要表格是动态的,因为它应该能够接受任意数量的CSVFields(至少 1 个)。根据Java Form Documentation,似乎我应该为 CSVField 注册一个自定义 DataBinder,但是我找不到任何使用多个输入字符串执行此操作的示例。这个例子类似,但它只绑定一个字段。

这是我想要的用户输入类型的视频。我使用此示例代码来添加动态字段。文本字段(名称)和选择下拉项(类型)的组合是我需要绑定到 aCSVField然后添加到对象List<CSVField> fields中的。如何使用 Play 框架做到这一点?CSVData


编辑:在我的控制器中我试过这个

Form<CSVData> formData = Form.form(CSVData.class).bindFromRequest();

在我看来我试试这个

@helper.repeat(csvForm("fields"), min = 1) { csvField =>

    @multiDataField(csvField,
        label = "Column Name and Type",
        gsnTypes,
        help = "Enter the column names and respective types for the data items in the file")

}

这个模板multiDataField在哪里。但它没有正确绑定动态字段并在. 我认为我的问题是我不知道在我的模板中使用什么属性。有什么建议吗?fieldsnamemultiDataField

4

1 回答 1

3

您不需要任何客户数据绑定器。无需任何额外绑定注册即可支持具有复杂对象的列表。

在视图中您可以使用@repeatHelper,而在控制器中您已经做得很好了。

Here你有一个关于Play 和 Forms的完整示例,或者直接在TypeSafe

编辑

在重复块内,csvField是 List 中每个 Form 对象的一个​​实例。然后,您需要添加视图所需的所有 HTML 元素。例如(没有 Bootstrap 的简化):

@helper.repeat(csvForm("fields"), min = 1) { csvField =>
    Name: <input type="text" name='@csvField("name").name' value='@csvField("name").value'>
    Type: <input type="text" name='@csvField("type").name' value='@csvField("type").value'>
}

您可以使用Play 2.2.x 中提供的示例找到更完整的示例。要在 2.3.x 中编译它,可能需要进行一些更改并且不使用 Bootstrap 3.x,但逻辑是相同的。

编辑 (2)

如果你想动态添加元素到视图中,你需要注意在添加新元素时设置正确的数组编号。为此,您将需要使用 JQuery:

$('.addCSVField').click(function() {
    var CSVFields = $(this).parents('.CSVField');
    var template = $('.CSVField_template', CSVFields);
    template.before('<div class="clearfix CSVField">' + template.html() + '</div>');
    renumber();
})

$('.removeCSVField').click(function() {
    $(this).parents('.CSVField').remove();
    renumber(); 
})  

var renumber = function() {
    $('.CSVField').each(function(i) {
        $('input', this).each(function() {
            $(this).attr('name', $(this).attr('name').replace(/fields\[.+?\]/g, 'fields[' + i + ']'));
        })
    })
}

然后您需要将您的 HTML/Scala 代码更改为以下内容:

@fieldGroup(field: Field, className: String = "CSVField") = {
    <div class="well @className">
        <a class="removeCSVField btn danger pull-right">Remove this field</a>
        Name: <input type="text" name='@field("name").name' value='@field("name").value'>
        Type: <input type="text" name='@field("type").name' value='@field("type").value'>
    </div>
}   

@repeat(csvForm("fields")) { csvField =>
    @fieldGroup(csvField)
}

@**
 * Keep an hidden block that will be used as template for Javascript copy code
 **@
@fieldGroup(csvForm("fields[x]"),className = "CSVField_template")   
<a class="addCSVField btn success">Add another field</a>

并添加 CSS 样式.CSVField_template{display: none;}

我没有测试任何一个,所以它可能无法编译。但是,我只是遵循了与Forms 示例中类似的方法(播放 2.2.x

于 2015-02-16T09:00:10.320 回答