kutas
kutas

Reputation: 377

Symfony 4: pass custom data to Form Collection prototype

CollectionType field has special 'prototype' variable when 'allow_add' option is set to true. This variable can be used to render prototype html like this:

data-prototype="{{ form_widget(form.collectionfieldname.vars.prototype)|e('html_attr') }}"

It looks like 'prototype' is simply an instance of collection children FormView built with partial data (e.g. name is set to "__name__" while most other vars are left blank).

Where all this magic happens? Is it possible to modify what data is passed to prototype view while building form? For example, I would like to change default value of "value" variable from blank to "__val__" (outside of Twig template).

Upvotes: 1

Views: 1864

Answers (1)

kutas
kutas

Reputation: 377

Answer to own question - values defined in "entry_options" setting are used to build prototype. It is possible to pass these values to form builder like this:

$builder
            ->add('email', CollectionType::class, array(
                ...
                'entry_options' => array(
                    'someoption' => 'somevalue',
                ),
                ...
                ))

If this is not enough, default behaviour can be modified by overriding "buildForm" method in "CollectionType" class which is responsible for collecting options and building prototype:

class CollectionType extends AbstractType
{
    ...

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        if ($options['allow_add'] && $options['prototype']) {
            $prototypeOptions = array_replace(array(
                'required' => $options['required'],
                'label' => $options['prototype_name'].'label__',
            ), $options['entry_options']);

            if (null !== $options['prototype_data']) {
                $prototypeOptions['data'] = $options['prototype_data'];
            }

            $prototype = $builder->create($options['prototype_name'], $options['entry_type'], $prototypeOptions);
            $builder->setAttribute('prototype', $prototype->getForm());
        }

        ...
    }
...
}

Upvotes: 2

Related Questions