Reputation: 4766
I have a template with multiple carts. There can be a variable amount of carts, there's no fixed limit.
In each cart I want to have a form where the user can select a country. If he submits the form the shipping costs should be established.
Now I'm doing the following to achieve it in twig:
{% for cart in carts %}
{# Some template stuff #}
{{ form_start(form) }}
<div class="form-input">
<label for="country" class="middle-color">Country <span class="active-color">*</span></label>
{{ form_widget(form.country) }}
{{ form_end(form) }}
{% endfor %}
This is my form builder:
$form = $this->createFormBuilder()
->add('country', 'choice', array('choice_list' => $choiceList, 'label' => 'country',
'attr' => array('class' => "custom-selectbox dark-color light-gradient")))
->getForm();
Now the problem is that this logic works fine for the first cart, but there's no form displayed for further carts. How can I deal with this?
Upvotes: 8
Views: 7596
Reputation: 4316
For Symfony 5 and 6 you can do
$formBuilder = $this->createFormBuilder()->add('...');
return $this->render('list.html.twig', ['formBuilder' => $formBuilder];
and in your twig
{% for cart in carts %}
{# Some template stuff #}
{% set form = formBuilder.form.createView %}
{{ form_start(form) }}
<div class="form-input">
<label for="country" class="middle-color">Country <span class="active-color">*</span></label>
{{ form_widget(form.country) }}
{{ form_end(form) }}
{% endfor %}
Upvotes: 0
Reputation: 2745
I came across this and another question about the similar issue. You can find my first answer for a solution here.
To wrap it up, I did not call the createView()
function on the form in the controller, as usually done when passing the form to the view, but in the twig view itself.
E.g. in your controller action you do return the form object itself:
return $this->render('AppBundle:Cart:list.html.twig', ['formObject' => $form];
and in your view you would set the form in each loop:
{% for cart in carts %}
{# Some template stuff #}
{% set form = formObject.createView %}
{{ form_start(form) }}
<div class="form-input">
<label for="country" class="middle-color">Country <span class="active-color">*</span></label>
{{ form_widget(form.country) }}
{{ form_end(form) }}
{% endfor %}
Upvotes: 17
Reputation: 2694
You should use collection form type. Here is a guide to start with How to Embed a Collection of Forms
P.S. Notice that after rendering a form widget Form component marks it as rendered and does not render once more.
Upvotes: -1