Home > Software engineering >  Symfony Form CollectionType with predefined/static rows
Symfony Form CollectionType with predefined/static rows

Time:05-22

I am trying to create a CollectionType form with predefined/static rows (not a dynamic form w/JS).

This does what I want:

$formBuilder = $this->createFormBuilder()->add('titles', CollectionType::class, [
    'entry_type' => TextType::class,
    'data' => ['en' => '', 'de' => ''],
]);

but this doesn’t work (it results in no rows at all in the form):

$formBuilder = $this->createFormBuilder()->add('titles', CollectionType::class, [
    'entry_type' => TextType::class,
]);
$formBuilder->get('titles')->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
    $data = ['en' => '', 'de' => ''];
    $event->setData($data);
});

In the end, I am looking for a simple form like so:

<form name="form" method="post">
    <div id="form">
        <div><label>Titles</label>
            <div id="form_titles">
            <div><label for="form_titles_en">En</label>
                <input type="text" id="form_titles_en" name="form[titles][en]">
            </div>
            <div><label for="form_titles_de">De</label>
                <input type="text" id="form_titles_de" name="form[titles][de]">
            </div>
        </div>
    </div>
</form>

I need the second approach for various reasons. Does anyone have a solution?

FYI: My current platform is Symfony 5.4 and Php 8.1 but I would like this solution to work with Php7.4 as well as Symfony 6

CodePudding user response:

Thank you to @Bossman for giving me direction. This is how I solved the problem.

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use App\LocaleProvider;

class TranslationCollectionType extends AbstractType
{
    private LocaleProvider $localeProvider;

    public function __construct(LocaleProvider $localeProvider)
    {
        $this->localeProvider = $localeProvider;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        foreach ($this->localeProvider->getSupportedLocaleNames() as $name => $value) {
            $builder->add($value, TextType::class, [
                'label' => $name,
            ]);
        }
    }
}

Then add to the form:

$builder->add('Titles', TranslationCollectionType::class);
  • Related