How can I render an individual field (single radio/checkbox input field) in Twig in Symfony 2.6?
Let's say I have a simple form:
class TransportType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('transport', 'choice', array(
'choices' => array(
'road' => 'Car/bus',
'train' => 'Train',
),
'expanded' => true,
'multiple' => false
));
}
In previous Symfony2 versions I could just use:
{{ form_widget(form.transport.road) }}
{{ form_widget(form.transport.train) }}
to render individual radio buttons, but it doesn't seem to work anymore. I know I can use:
{{ form_widget(form.transport[0]) }}
{{ form_widget(form.transport[1]) }}
but it's less flexible. Of course I can iterate over the collection and check for name, but this seems like unnecessary hassle. Isn't there an easier way?
I tried offsetGet
(which is supposed to return a child by name
), but it also works only with array index.
It appears this is not possible with the latest versions of Symfony (i.e. >= 2.6). I recall in previous versions, when the form builder displayed the choices
array, it was generating the choices like this:
<select>
<option value="road">Car/Bus</option>
<option value="train">Train</option>
</select>
This, however, has been changed in the recent versions to the following:
<select>
<option value="0">Car/Bus</option>
<option value="1">Train</option>
</select>
The selected option is then normalized and then you get the expected value
you've set in the FormType
class. You can read more about normalization here.
Also, If you write {{ debug(form.transport) }}
in Symfony >= 2.6, you can see the form/field array and what you can use from it.
Since Symfony 2.7 you can set choices forms name through the choice_name option.
Try this:
{% for key, transportItem in form.transport.children %}
{{ form_widget(transportItem) }}
{% endfor %}
here my solution i used in my own project
{{form_label(form.transport)}}
{% for key, item in form.transport.children %}
<div class="custom-radio">
<label for="{{item.vars.id}}">{{item.vars.label}}</label>
<input
type="radio"
value="{{item.vars.value}}"
id=" {{item.vars.id}}"
name="{{item.vars.full_name}}"
{{ item.vars.checked ? 'checked' : '' }}
>
</div>
{% endfor %}
or you can use a form theming
{% form_theme form _self %}
{%- block choice_widget_expanded -%}
{%- for child in form %}
<div class="custom-radio">
{{- form_label(child) -}}
{{- form_widget(child) -}}
</div>
{% endfor -%}
{%- endblock choice_widget_expanded -%}
{{form_widget(form)}}