I have a \"Question\" entity that has a \"Answer\" that has a list of \"Alternatives\" as below:
public class Question extends BaseEntity {
private Stri
This is documented here, specifically at how to handle repeated values. Of course, documentation can always be improved. Please open an issue raising this problem. Also, this does not represent that the framework is becoming obsolete or being overtaken by others (in fact, Play 2.5 is close to being released and the community is growing).
Anyway, here is an comprehensive example about how to do a parent/child form like you described. Keep in mind that I didn't care about styling the forms.
models/Question.java
:
package models;
public class Question {
public String text;
public String sourceCode;
public String complement;
public Answer answer;
}
models/Answer.java
:
package models;
import java.util.List;
public class Answer {
public List<Alternative> alternatives;
}
models/Alternative.java
:
package models;
public class Alternative {
public boolean correct;
public String statement;
}
Now, I have the following action that just returns the Question
object and its children as a JSON (since we are just interested in how to submit this kind of data):
package controllers;
import models.Question;
import play.data.Form;
import play.libs.Json;
import play.mvc.*;
import views.html.*;
import static play.data.Form.form;
public class Application extends Controller {
public Result index() {
Form<Question> form = form(Question.class);
return ok(index.render(form));
}
public Result post() {
Form<Question> form = form(Question.class).bindFromRequest();
Question question = form.get();
return ok(Json.toJson(question));
}
}
Notice at the index
action how I've declared a Form<Question>
and passed it as an argument to the view. You can see more information about how to define a form at the docs. Let's see our routes:
GET / controllers.Application.index()
POST /save controllers.Application.post()
Finally, we need to create the form that will populate and submit the data:
@(questionForm: Form[Question])
@main("Welcome to Play") {
@helper.form(action = routes.Application.post()) {
<h2>Question:</h2>
@helper.inputText(questionForm("text"))
@helper.inputText(questionForm("sourceCode"))
@helper.inputText(questionForm("complement"))
<h3>Answers:</h3>
@helper.repeat(questionForm("answer.alternatives"), min = 2) { alternative =>
@helper.checkbox(alternative("correct"))
@helper.inputText(alternative("statement"))
}
<button type="submit">Save</button>
}
}
Basically the form was created using the form helpers which will handle most of the aspects of how the form works (like showing errors, per instance). Special attention to the @helper.repeat
tag: it will create the following markup (omitting irrelevant parts):
<h3>Answers:</h3>
<label>answer.alternatives.0.correct</label>
<input type="checkbox" name="answer.alternatives[0].correct" value=""/>
<label>answer.alternatives.0.statement</label>
<input type="text" name="answer.alternatives[0].statement" value=""/>
<label>answer.alternatives.1.correct</label>
<input type="checkbox" name="answer.alternatives[1].correct" value="" />
<label>answer.alternatives.1.statement</label>
<input type="text" name="answer.alternatives[1].statement" value=""/>
Notice how the parameters are named to represent an order and also related different fields of the alternative
object.
Finally, after filling and submitting the form, you will get the following JSON:
{
"text": "Question text",
"sourceCode": "Question source",
"complement": "Question complement",
"answer": {
"alternatives": [
{
"correct": true,
"statement": "Statement 1"
},
{
"correct": false,
"statement": "Statement 2"
}
]
}
}