KhorneHoly
KhorneHoly

Reputation: 4766

How to render same form multiple times in Symfony2?

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

Answers (3)

allan.simon
allan.simon

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

lordrhodos
lordrhodos

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

Andrii Mishchenko
Andrii Mishchenko

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

Related Questions