I want to render a form which has multiple Entities of same Class. I will display 2 fields, Price(type=text) and Enabled(type=checkbox).
I don\'t know how many I wil
I found the solution,
the way I was creating the form in Controller was wrong! I had to do the following:
$pricingForm = $this->createFormBuilder(array('prices'=>$prices))
->add('prices','collection',array(
'required' => true,
'allow_add' => true,
'type' => new PricingType(),
))
->getForm()
;
"allow_add => true" is necessary when working with collection, otherwise it will NOT add any of PricingType collection of entities to the form.
Then, because the form is built inside the controller "$this->createFormBuilder(array('prices'=>$prices))
" , $prices
array must be passed as an array with array keyname same as the one used in "->add('prices','collection',array(...)
" , which is 'prices'
so Symfony will know what to bind where. $prices
is an array of Pricing objects array(0 => new Pricing())
.
In my PricingType I have:
class PricingType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('price', 'text', array(
'label' => false,
'required' => true
))
->add('enabled','checkbox',array(
'label' => 'Use this currency',
))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'XXX\XXX\Entity\Pricing',
'csrf_protection' => false
));
}
public function getName()
{
return 'pricingtype';
}
}
Here I need to have control over label attribute. I could not find the way for it( if anyone knows please post how to). I override my twig template as follows:
On the top we need next line of code:
{% form_theme form_pricing _self %}
Then override row and widget as follows (it was a nightmare to debug):
{% block _form_prices_entry_row %}
{% spaceless %}
{{ form_widget(form) }}
{% endspaceless %}
{% endblock %}
{% block _form_prices_entry_widget %}
{% spaceless %}
{{ form_row(form.price, { 'label' : form.vars.value.getCurrency().getTitle() } ) }}
{{ form_row(form.enabled) }}
{% endspaceless %}
{% endblock %}
In the body then, render form elements as follows:
{% for price in form_pricing.prices %}
<div class="price-row">{{ form_row(price) }}</div>
{% endfor %}
I really hope this will help you guyz. It was a real nightmare to debug especially the twig file, I did it thanks to my clever colleague.
I think you have missed a for loop in your twig file Check this example:
{# store the prototype on the data-prototype attribute #}
<ul id="email-fields-list" data-prototype="{{ form_widget(form.emails.vars.prototype)|e }}">
{% for emailField in form.emails %}
<li>
{{ form_errors(emailField) }}
{{ form_widget(emailField) }}
</li>
{% endfor %}
</ul>
See the loop, I think that you need to add in your twig file.
In addition to loops you need to add JavaScript also.
Check this link:
http://symfony.com/doc/current/reference/forms/types/collection.html#adding-and-removing-items
Check the complete code. It will help you out to generate multiple entity forms from a single entity class using collection field type.