How to make form_rest() not display a field with Symfony2?
PhpFormsSymfonyTwigPhp Problem Overview
I've started to use Symfony2 but I've some problems.
I wanted to render fields by hand but it doesn't work because my field yet rendered by me is displayed with the form_rest()
function too, so I have two same fields.
Here is my code :
<div>
{{ form_errors(form.contenu) }}
<textarea id="{{ form.contenu.vars.id }}" name="{{ form.contenu.vars.full_name }}">{{ form.contenu.vars.value }}</textarea>
</div>
And, at the form's end, I must put this :
{{ form_rest(form) }}
But it displays the "contenu" field :(
Do you have an idea of what's the problem ?
Php Solutions
Solution 1 - Php
Another option is to explicitly mark the field as rendered:
{% do form.contenu.setRendered %}
Solution 2 - Php
Another in my opinion less hacky way to do it is this:
{{ form_widget(form._token) }} // render the CSRF Token
{{ form_end(form, {'render_rest': false}) }} // do not render anything else
It's from the official documentation (v3.0) so it's pretty much best practise i guess.
Solution 3 - Php
{{ form_rest(form) }}
goes at the very end, after rendering each field "manually". If you are using it for the CSRF token you can always render it with:
{# Token CSRF #}
{{ form_widget(form._token) }}
Solution 4 - Php
The situation in which you don't want to show some field suggests badly designed form. You could feed some argument(s) into it's __construct
to make it conditional (say, include/exclude some fields) or you could just create separate Form
classes (which is, in my opinion, a bit overkill).
I had common case few months ago when form differed when user inserted/updated records. It was something like this:
...
public function __construct($isUpdateForm){
$this->isUpdateForm= $isUpdateForm;
}
public function buildForm(FormBuilder $builder, array $options){
....
$builder->add('some_filed', 'text', ..... );
if ( $this->isUpdateForm ){
$builder->add(.....);
}
....
}
....
If for some reasons you're not able to refactor form class you could still display unwanted fields but wrap them into <div>
which has CSS display:none
attribute. That way "they are still there" (and by all means are processed normally) but are not visible to user.
Hope this helps...