Tim
Tim

Reputation: 71

Symfony 2.8.x: Custom FormType overwrites form variables

I have a form with multiple fields. I also use some custom form-types, for example a DivType to add text, buttons, pictures or other stuff, not mapped to the database.

Upgrading the code to the Symfony 2.8 syntax results in undisired behavour.

My form:

class ExampleType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options) {

        // A couple of fields, for example field1
        $builder->add('field1', 'text', array(
            //  text field
        ));

        // A div element
        $builder->add('div_id_1', new DivType(), array(
            'content' => 'Just some content in the first div',
        ));

        // Another div
        $builder->add('div_id_2', new DivType(), array(
            'content' => 'A div with some images, buttons or other cool stuff',
        ));

    }
}

My DivType.php:

class DivType extends AbstractType {

    private $content;
    private $id;

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $this->content = $options['content'];
        $this->id = $builder->getName();
    }

    public function buildView(FormView $view, FormInterface $form, array $options) {
        $view->vars['div_content'] = $this->content;
        $view->vars['div_id'] = $this->id;
    }

    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setDefaults(array (
            'mapped' => false,
            'content' => false,
        ));
        $resolver->setDefined(array('div_id'));
    }

    public function getName() {
        return 'div';
    }
    public function getBlockPrefix() {
        return 'div';
    }

}

My template code:

{% block div_row %}
    <div id="{{ div_id }}">
    {% if div_content is defined and div_content %}
        {{ div_content }}
    {% endif %}
    </div>
{% endblock %}

Result of the div's (so far it is working OK :-):

...
<div id="div_id_1">
    Just some content in the first div
</div>
<div id="div_id_2">
    A div with some images, buttons or other cool stuff
</div>
...

Now I am upgrading to symfony 2.8:
In the deprecation messages in the profiler this line shows up: "Passing type instances to FormBuilder::add(), Form::add() or the FormFactory is deprecated since version 2.8 and will not be supported in 3.0. Use the fully-qualified type class name instead (MyBundle\Form\Type\DivType)"

So I changed the syntax in my ExampleType class to the new syntax (DivType::class):

$builder->add('div_id_1', DivType::class, array(
    'content' => 'Just some content in the first div',
));
$builder->add('div_id_2', DivType::class, array(
    'content' => 'A div with some images, buttons or other cool stuff',
));

Now the result is not what I was expecting. I get the number of div's added to the form, but all are overwritten by the values of the last added element, which obviously is not very usefull...

<div id="div_id_2">
    A div with some images, buttons or other cool stuff
</div>
<div id="div_id_2">
    A div with some images, buttons or other cool stuff
</div>

Does somebody have a clue what I'm doing wrong?
Or is there an alternative approach I can use to add custom formtypes?

Upvotes: 2

Views: 300

Answers (1)

Tim
Tim

Reputation: 71

Thanks to Cerad, I was able to solve the problem! Apparently I had made it too complicated... using the $options in buildView method and removing them from the buildForm method did do the job.

My new DivType:

class DivType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {

    }

    public function buildView(FormView $view, FormInterface $form, array $options) {
        $view->vars['div_content'] = $options['content'];
        $view->vars['div_id'] = $options['div_id'];
    }

    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setDefaults(array (
            'mapped' => false,
            'content' => false,
        ));
        $resolver->setDefined(array('div_id'));
    }

    public function getBlockPrefix() {
        return 'div';
    }

}

Maybe a better and more cleaner way is to use the element-id directly in twig, using the variable 'form.vars.name' for the id, instead of adding the extra variable 'div_id':

<div id="{{ form.vars.name }}">

Upvotes: 2

Related Questions