Zoltán Süle Zoltán Süle - 2 years ago 257
Twig Question

wrap checkboxes with custom html in Twig template using form entity fieldtype (Symfony3)

I would like to wrap the checkboxes with custom HTML in twig template when Symfony3 renders the form.

Instead of this:

<input type="checkbox" id="form_role_1" name="form[role][]" value="1" />
<label for="form_role_1">ROLE 1</label>
<input type="checkbox" id="form_role_2" name="form[role][]" value="2" />
<label for="form_role_2">ROLE 2</label>
<input type="checkbox" id="form_role_3" name="form[role][]" value="3" />
<label for="form_role_3">ROLE 3</label>


I would like to get something like this:

<div class="input-group">
<input type="checkbox" id="form_role_1" name="form[role][]" value="1" />
<label for="form_role_1">ROLE 1</label>
</div>

<div class="input-group">
<input type="checkbox" id="form_role_2" name="form[role][]" value="2" />
<label for="form_role_2">ROLE 2</label>
</div>

<div class="input-group">
<input type="checkbox" id="form_role_3" name="form[role][]" value="3" />
<label for="form_role_3">ROLE 3</label>
</div>


in the controller action:

$form = $this->createForm(RolesFormType::class, $roles);
$form->handleRequest($request);

return $this->render(
'role/edit_roles.html.twig',
array(
'form' => $form->createView()
)
);


in the form type:

class RolesFormType extends AbstractType
{

public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('role', EntityType::class, array(
'label' => 'form.elements.roles',
'class' => 'RoleBundle\Entity\Role',
'choice_label' => 'role_name',
'expanded' => true,
'multiple' => true
));
}
}


the classic template looks like this:

<div class="container-fluid">
<div class="row">

{{ form_start(form, {'method': "POST"}) }}

<div class="col-md-12">

<div class="form-group">
{{ form_errors(form.role) }}
{{ form_widget(form.role, {}) }}
</div>

</div>

{{ form_rest(form) }}
{{ form_end(form) }}

</div>
</div>


I tried it this way in the twig template, but only the labels were rendered:

<div class="container-fluid">
<div class="row">

{{ form_start(form, {'method': "POST"}) }}

<div class="col-md-12">

{% for role in form.role %}
<div class="input-group">
{{ form_label(role) }}
{{ form_widget(role) }}
</div>
{% endfor %}

</div>

{{ form_rest(form) }}
{{ form_end(form) }}

</div>
</div>


Is ii possible without creating a new field type?

solution



concerning @xabbuh's answer I found the solution at How to Customize Form Rendering in Symfony 3

I created a folder in my Bundle:
src/RoleBundle/Resources/views/form


and I put a new file (
fields.html.twig
) into it with this content

{%- block choice_widget_expanded -%}
<div {{ block('widget_container_attributes') }}>
{%- for child in form %}
<div class="input-group">
{{- form_widget(child) -}}
{{- form_label(child, null, {translation_domain: choice_translation_domain}) -}}
</div>
{% endfor -%}
</div>
{%- endblock choice_widget_expanded -%}


In the meantime I found another question which deals with this problem:
Overriding symfony radio widget

Answer Source

You can customise the rendering of your form using a custom form theme. You can so either on the project level or even do that just for a particular form (see How to Customize Form Rendering and How to Work with Form Themes for more information).

Your example looks like you need to override the choice_widget and choice_label

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download