使用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
是包含两个字符串的自定义类型。我需要表单是动态的,因为它应该能够接受任意数量的CSVField
s(至少1)。根据{{3}},似乎我应该为CSVField注册自定义DataBinder,但是我找不到任何使用多个输入字符串执行此操作的示例。 Java Form Documentation类似,但它只绑定一个字段。
This example我希望拥有哪种类型的用户输入。我使用Here is a video制作了我的观点。文本字段(名称)和选择下拉项(类型)的组合是我需要绑定到CSVField
然后添加到List<CSVField> fields
对象中的CSVData
的组合。 如何使用Play框架执行此操作?
编辑:在我的控制器中,我尝试了这个
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
是this example code for adding dynamic fields模板的位置。但它没有正确绑定动态字段,并在fields
上抛出了无效的验证错误。我认为我的问题是我不知道在name
模板中使用哪些multiDataField
属性。有什么建议吗?
答案 0 :(得分:3)
您不需要任何客户数据存储器。支持具有复杂对象的列表,无需任何其他绑定注册。
在视图中,您可以使用@repeat
助手,在控制器中,您已经做得很好。
这里有一个关于Play and 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'>
}
您可以使用samples provide in 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 example (play 2.2.x
类似的方式进行了跟踪