Let's start with the @phoneField
function:
@phoneField(field: Field, className: String = "phone") = {
@input(field, '_label -> "Phone numbers", '_class -> className) { (id, name, value, _) =>
<input type="text" name="@name" value="@value">
<a class="removePhone btn danger">Remove</a>
}
}
@input
is a helper (i.e. function) that allows you create html for the field yourself. This is needed in this context because we want to add .removePhone
button. So @phoneField
simply takes instance of Field
and constructs html input and remove-link.
Now, what about @repeat
?
@repeat(field("phones"), min = 0) { phone =>
@phoneField(phone)
}
In the app/controllers/Contacts.scala defined contactForm and there you can see that "phones" field defined as list(text). It is a sort of collection with elements that are text fields.
So @repeat will iterate over field("phones")
and pass each text field to the @phoneField
. Important thing that all fields that will go to @phoneField will have names like "phones[0]", "phones1", ....
Now things got interesting.
@phoneField(
field("phones[x]"),
className = "phone_template"
)
constructs a template for the javascript function that will copy it's content to the page on response to "add phone field" button. Looks like field("phones[x]")
constructs empty field with name "phones[x]" similar to what @repeat
is generating. Then whole construct will create a phone field (and remove-link) with name "phones[x]" and empty value.
When you'll look at the javascript code you will see that when user clicks "Add a phone number" link javascript callback will be executed that will copy the html from the template to the dom under <div class="phones">
, and will renumber all .phone input which name matches /phones\[.+\]/
I hope that you have read Using the form template helpers.