I have lots of collections to create, and don't want to create a FormType for each entry_type, because they are used only once.
So instead of giving a form type FQCN in the entry_type
option, I tried to put a fresh Type
directly coming from the form builder:
$type = $this
->get('form.factory')
->createBuilder(Type\FormType::class)
->add('label', Type\TextType::class, [
'label' => 'Key',
])
->add('value', Type\TextType::class, [
'label' => 'Value',
])
->getType()
;
$form = $this
->get('form.factory')
->createBuilder(Type\FormType::class)
->add('hash', Type\CollectionType::class, [
'entry_type' => $type,
'entry_options' => [],
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'required' => false,
'delete_empty' => true,
])
->getForm()
;
But for some reasons, the prototype is invalid:
<div class="form-group">
<label class="control-label required">__name__label__</label>
<div id="form_hash___name__"></div>
</div>
All child fields from my manually-created $type
are missing. Where is my mistake?
I found my answer myself finally.
As the ->getType()
I was using is in the FormBuilder
class, but not in the FormBuilderInterface
, I assume this was a bad idea to use it. Moreover, the FormType
instance returned was empty (a form type, but no children).
So I changed my stand and created the following EntryType
class (yes, I'm using a Form Type class, but only a generic one for all my future collections):
<?php
namespace AppBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class EntryType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
foreach ($options['fields'] as $field) {
$builder->add($field['name'], $field['type'], $field['options']);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'fields' => [],
]);
}
}
I can now use arbitrary fields in my collection using this fields
option:
use Symfony\Component\Form\Extension\Core\Type;
use AppBundle\Form\Type\EntryType;
// ...
$form = $this
->get('form.factory')
->createBuilder(Type\FormType::class)
->add('hash', Type\CollectionType::class, [
'entry_type' => EntryType::class,
'entry_options' => [
'fields' => [
[
'name' => 'key',
'type' => Type\TextType::class,
'options' => [
'label' => 'Key',
],
], [
'name' => 'value',
'type' => Type\TextType::class,
'options' => [
'label' => 'Value',
],
],
],
],
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'required' => false,
'delete_empty' => true,
])
->getForm()
;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With