PHP, Uncategorized
Customize form collection rendering in Symfony
août 9, 2019
-
Form builder in Symfony is very powerfurl, you can easily build complex forms.
One of the best option is CollectionType, it means you can embed a collection of subforms (or Entities related) into a main form.
According to this documentation : https://symfony.com/doc/3.4/form/form_customization.html#how-to-customize-a-collection-prototype, you can customize displaying.
But, this documentation disappeared in Symfony 4.
To quickly display a collection into a very complex layout, you can use Twig blocks extensions, or directly customize your view.
Let’s suppose we have this form :
class TaskListType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options = array())
{
$builder->add('tasks', CollectionType::class, array(
'entry_type' => TaskType::class,
));
}
}
class TaskType
{
public function buildForm(FormBuilderInterface $builder, array $options = array())
{
$builder
->add('content')
->add('active', CheckboxType::class);
}
}
You can use these blocks to customize the layout :
{% block _task_list_entry_tasks_widget %}
{# collection widgets of TaskType #}
{% endblock %}
{% block _task_list_entry_tasks_entry_widget %}
{# inner label of TaskType #}
{% endblock %}
{% block _task_list_entry_tasks_entry_content_widget %}
{# field content of TaskType #}
{% endblock %}
{% block _task_list_entry_tasks_entry_content_label %}
{# label content of TaskType #}
{% endblock %}
Or in your view :
{% for task in formTaskList.tasks %}
<div class="form-group row align-items-center">
<label class="col-md-3 label-control">
{# access task data using task.vars.data #}
Task {{ task.vars.data['id'] }}
</label>
<div class="col-md-6">
{{ form_widget(task.children.content) }}
</div>
<div class="col-md-1">
{{ form_widget(task.children.active) }}
</div>
</div>
{% endfor %}
And if you need to pass options of the main form to the child form :
class TaskListType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options = array())
{
$builder->add('tasks', CollectionType::class, array(
'entry_type' => TaskType::class,
'entry_options' => [
'label' => null,
// access $options['colorsList'] in TaskType
'colorsList' => $options['colorsList']
],
));
}
}