Reputation: 7768
I have a form with a repeated field:
case class MyForm(topics: List[Int])
val myForm: Form[MyForm] = Form(
mapping(
"topics" -> list(number)
)(MyForm.apply _)(MyForm.unapply _)
)
And the corresponding view:
@form(...) {
<h2>Topics of interest:</h2>
@for(Topic(id, name, _) <- Topics.all) {
@checkbox(
bidForm(s"topics[$id]"),
'_label -> (name + ":").capitalize,
'value -> id.toString)
}
<input type="submit" id="submit" value="Save">
}
So far so good, if there is an error in the field and I re-render it passing myForm.bindFromRequest
.
I would like to pre fill the form with data from my database. With other types of fields (number
, text
, option()
and so on) I am able to populate an existingMyForm
with something like this:
val existingMyForm = myForm.fill(MyForm(
// Queries the database and return a list of case classes with field id: Int
Topics.of(member).map(_.id)
))
However with list
this approach fails and I have to manually do the mapping:
val existingMyForm = myForm.bind(
Topics.of(member).map(t => ("topics[%s]".format(t.id), t.id.toString)).toMap
)
Is there a better way to do this?
Upvotes: 2
Views: 1294
Reputation: 1723
I believe you need to explicitly pass a List[Int] to the MyForm constructor, i.e.
val existingMyForm = myForm.fill(MyForm(
Topics.of(member).map(_.id).toList
))
EDIT - Here is my basic implementation which worked for Play 2.1.1 Scala:
case class MyForm(topics: List[Int])
case class Topic(id: Int)
val myForm: Form[MyForm] = Form(
mapping("topics" -> list(number))(MyForm.apply _)(MyForm.unapply _)
)
val topicList:List[Topic] = List(Topic(1), Topic(2), Topic(3))
def test = Action { implicit req =>
val existingMyForm = myForm.fill(MyForm(
topicList.map(_.id)
))
Ok(views.html.test(existingMyForm))
}
Upvotes: 1