2
votes

I have a little problem in twig to render symfony forms, so, first I will explain the context of it.

In Twig, blocks are defined in a certain order on a template:

{# base.layout.html.twig #}

{% block firstBlock %}
{% endblock firstBlock %}

{% block secondBlock %}
{% endblock secondBlock %}

And when we extends this template we can write this:

{# child.layout.html.twig #}
{% embed "base.layout.html.twig" %}

{% block secondBlock %}
   {{ form_widget(form.submit_button) }}
{% endblock secondBlock %}

{% block firstBlock %}
   {{ form_widget(form.some_field) }}
   {{ form_rest(form) }}
{% endblock firstBlock %}

So the problem is with the form() functions in twig which renders Symfony forms.

I am trying to generate a submit button at the very end of a modal window but the problem is that form_rest() renders all parts of the form not already rendered.

There is a little fix to avoid form_rest to render form.submit_button, it's to set form.submit_button as an already rendered field with:

{% do form.submit_button .setRendered %}

But with this form.submit_button is never rendered

Of course the finality of all this is to don't remove the form_rest instruction.

So I search something to unset rendered value of form.submit_button after the form_rest instruction or even better a way to choose the order of blocks generation of a template.

Like this:

{% block secondBlock with(1) %}
   {{ form_widget(form.submit_button) }}
{% endblock secondBlock %}

{% block firstBlock with(2) %}
   {{ form_widget(form.some_field) }}
   {{ form_rest(form) }}
{% endblock firstBlock %}

Thank you for your help !

2
What if you add {{ form_rest(form) }} to secondBlock ? - sakhunzai
@sakhunzai If I do like this I will ruin my view, the problem is to rendered all the form fields at a given position in template and then rendered submit button at a lower position in the same template. So a body block (in this exemple it's firstBlock) and a footer block (secondBlock) - Tanaky
then check what Alain Tiemblo has suggested below - sakhunzai

2 Answers

0
votes

If it is just for a submit button, you can remove it from your form type and write it in html, it is'nt a problem, and it will work.

The problem is that you render first the rest (including the button), and after you try to render the button but it is already rendered...

Of course, your html button must be inside < form > tags.

If you want to keep your submit button from your form type,

1 solution is to move it using some javascript ...

2 solution is to mark it as rendered (as you have done), and write the exact html of your submit button in the place you want.

[edit] You can also render every field of your form in the first block, render your submit button in the second block, and put form_rest after all these (as all the fields have been rendered, it will not have something to render, this is a solution also)

0
votes

If that's just a matter of a submit button that has no logic and no mapping at all, the easiest way is to render your submit button in HTML directly and removing it from your form.

<input type="submit" value="Submit"> {# ¯\_(ツ)_/¯ #}

Another solution is to put your modal in a modal_layout.html.twig, and then use the embed tag that is exactly made for this kind of issues.

modal_layout.html.twig

<div class="modal">
  <div class="form">
     {% block form_part %}{% endblock %}
  </div>
  <div class="submit pull-right">
     {% block submit_part %}{% endblock %}
  </div>
</div>

your_page.html.twig

{% embed 'modal_layout.html.twig' %}
    {% block submit_part %}
        {{ form_row(form.submit_button) }}
    {% endblock %}
    {% block form_part %}
        {{ form(form) }} {# won't render submit again #}
    {% endblock %}
{% endembed %}

But IMO the second solution, even if it appears cleaner, does not worth it for a stupid submit button.

Cheers