Play Framework - 为动态字段注册自定义 DataBinder

2024-01-02

使用 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... }

and

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

...}

制作表格输入时的困难CSVData是我有这个嵌套List<CSVField>属性和CSVField是包含两个字符串的自定义类型。我需要表单是动态的,因为它应该能够接受任意数量的CSVFields(至少 1)。根据Java 表单文档 https://www.playframework.com/documentation/2.3.x/JavaForms,似乎我应该为 CSVField 注册一个自定义 DataBinder,但是我找不到任何使用多个输入字符串执行此操作的示例。这个例子 https://stackoverflow.com/questions/8729444/how-to-bind-complex-types-in-play-framework-2-0类似,不过只绑定一个字段。

这是一个视频 https://www.youtube.com/watch?v=3u0cJURbuCU我想要什么类型的用户输入。我使用了我的观点此示例代码用于添加动态字段 http://jsfiddle.net/aaki/hMJEy/1/。文本字段(名称)和选择下拉项(类型)的组合是我需要绑定到CSVField然后添加到List<CSVField> fields in the CSVData目的。我如何使用 Play 框架来做到这一点?


EDIT:在我的控制器中我尝试过这个

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")

}

Where multiDataField is this http://pastebin.com/SN4gWE3s模板。但它没有正确绑定动态字段并抛出无效的验证错误fields。我想我的问题是我不知道什么name在我的中使用的属性multiDataField模板。有什么建议吗?


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

在视图中您可以使用@repeat助手和控制器中你已经做得很好了。

这里有一个完整的例子游戏与形式 http://ics-software-engineering.github.io/play-example-form/,或直接在TypeSafe http://typesafe.com/activator/template/play-example-form

EDIT

在重复块内,csvField是列表中每个 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 中提供的示例 https://github.com/playframework/playframework/tree/2.2.x/samples/java/forms。要在 2.3.x 中编译它,可能需要稍微更改一些内容,并且不使用 Bootstrap 3.x,但逻辑是相同的。

EDIT (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;}

我没有测试任何内容,所以它可能无法编译。然而,我只是遵循了与表单示例(玩 2.2.x https://github.com/playframework/playframework/blob/2.2.x/samples/java/forms/app/views/contact/form.scala.html#L61

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Play Framework - 为动态字段注册自定义 DataBinder 的相关文章

随机推荐