Using Play 2.3.7 (Java) I have the following scenario.
I have a class CSVData
which contains a list of type CSVField
. Here are the attributes for these classes:
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;
...}
The difficulty when making a form to input CSVData
is that I have this nested List<CSVField>
attribute and CSVField
is a custom type containing two strings. I need the form to be dynamic in that it should be able to accept an arbitrary amount of CSVField
s (at least 1). According to the Java Form Documentation, it seems like I should register a custom DataBinder for CSVField, however I can't find any examples that do this with multiple input strings. This example is similar, but it only binds one field.
Here is a video of what type of user input I would like to have. I made my view using this example code for adding dynamic fields. The combination of the text field (name) and select dropdown item (type) is what I need to bind to a CSVField
and then add to the List<CSVField> fields
in the CSVData
object. How can I do this using the Play Framework?
EDIT: In my controller I have tried this
Form<CSVData> formData = Form.form(CSVData.class).bindFromRequest();
And in the view I try this
@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 template. But it doesn't bind the dynamic fields properly and throws an invalid validation error on fields
. I think my problem is I don't know what name
attributes to use in my multiDataField
template. Any advice?
You don't need any customer databinder. Lists with complex objects are supported without any additional binding registration.
In the view you can use the
@repeat
Helper and in the controller you are already doing it well.Here you have a complete example about Play and Forms, or directly in TypeSafe
EDIT
Inside the repeat block,
csvField
is an instance of every Form object in your List. Then you will need to add all the HTML elements you need for your view. For example (simplified without Bootstrap):You can find a more complete example with the samples provide in Play 2.2.x. To compile it in 2.3.x maybe something need to be changed a bit and is not using Bootstrap 3.x, but the logic is the same.
EDIT (2)
If you want to add dynamically elements to the view, you will need to take care that when a new element is added, the right array number is set. For that you will need to use JQuery:
And then you will need to change your HTML/Scala code to something like that:
And to add a CSS style
.CSVField_template{display: none;}
I did not test any of that, so it may not compile. However, I just followed a similar apporach as in the Forms example (play 2.2.x