I have an entity User and an entity Address. There is a relation One-to-Many between User and Address :
class User
{
/**
* @orm:OneToMany(targetEntity="Address")
*/
protected $adresses;
[...]
}
I have a class AddressType, and class UserType :
class UserType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('addresses', 'collection', array('type' => new AddressType()));
}
[...]
}
In my controller, I build form with :
$form = $this->get('form.factory')->create(new UserType());
... and create view with :
return array('form' => $form->createView());
I display form field in my twig template with :
{{ form_errors(form.name) }}
{{ form_label(form.name) }}
{{ form_widget(form.name) }}
[...]
Okay. Now, how to display fields for one or more addresses ? (it's no {{ for_widget(form.adresses.zipcode) }}
nor {{ for_widget(form.adresses[0].zipcode) }}
...)
Any ideas ?
This is how I did it in my form template:
{{ form_errors(form.addresses) }}
{% for address in form.addresses %}
<div id="{{ 'address%sDivId'|format(loop.index) }}" class="userAddressItem">
<h5> Address #{{ loop.index }}</h5>
{{ form_errors(address) }}
{{ form_widget(address) }}
</div>
{% endfor %}
And I have a small action bar, driven by jQuery, that lets the user add and remove addresses. It is a simple script appending a new div to the container with the right HTML code. For the HTML, I just used the same output has Symfony but with updated index. For example, this would be the output for the street input text of the AddressType
form:
<input id="user_addresses_0_street" name="user[addresses][0][street]" ...>
Then, the next index Symfony will accept is 1 so the new input field you add would look like this:
<input id="user_addresses_1_street" name="user[addresses][1][street]" ...>
Note: The three dots are a remplacement for required="required" maxlength="255"
but could change depending on your needs.
You will need more HTML code than that to add a whole new AddressType
to the DOM of the browser but this give you the general idea.
Regards,
Matt
I should top that up with the fact that if you want to dynamically add fields, you need to set the key 'allow_add' to true in your collection field in UserType :
...
$builder->add('addresses', 'collection', array(
'type' => new AddressType(),
'allow_add' => true
));
Just spent hours trying to figure out what was missing, and at the time i'm writing the doc does not mention this yet. Hope it'll help fellow developers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With