0

I have an issue with Symfony 3.4 EntityType.

CategoryType.php

class CategoryType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title')
            ->add('spec', CollectionType::class, [
                'entry_type' => SpecificationType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'label' => false,
            ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Category::class,
        ));
    }
}

SpecificationType.php

class SpecificationType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('title', EntityType::class, [
            'class' => Specification::class,
            'label' => false,
        ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Specification::class,
        ));
    }

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

Form renders as expected: Title as Text field, and 2 select elements. But problem is rendered select element does not select selected value.

form.html.twig

{{ form_widget(form.title) }}
{{ form_widget(form.spec) }}

Result
enter image description here

Expected result
enter image description here

When in SpecificationType.php EntityType::class is replaced with TextField:class now form renders not 2 select elements bus 2 text inputs (expected behaviour) and values assigned are correct:
enter image description here

I started digging how these select elements are rendered in first place, and found that this block {%- block choice_widget_options -%} is responsible for rendering select element.

Inside this block is peace of code:

<option value="{{ choice.value }}"{% if choice.attr %}{% with { attr: choice.attr } %}{{ block('attributes') }}{% endwith %}{% endif %}{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option>

Exactly this condition: {% if choice is selectedchoice(value) %} selected="selected"{% endif %} is responsible for adding selected attribute to option. But value in selectedchoice(value) extension is somehow empty, that's why he is not marking option as selected.

Maybe anyone knows, how to solve this issue?

UPDATED

spec property is defined like this:

CategoryEntity.php

/**
 * @ORM\ManyToMany(targetEntity="Specification", inversedBy="categoryList")
 * @ORM\JoinTable(name="category_specification")
 */
private $spec;
2
  • Can you please show how spec property is defined in Category entity? Commented Jun 7, 2018 at 12:18
  • @Djengobarm please see updated section. Commented Jun 7, 2018 at 12:25

1 Answer 1

1

Found solution here.

As @Nickolaus wrote:

[..] You are having this problem because it is a compound form in your implementation and no simple form and symfony is unable to resolve which field created inside the subform needs to be used as source for the entity field

So solution is:

Refactor SpecificationType.php like this:

class SpecificationType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'class' => Specification::class,
            'label' => false,
        ));
    }

    public function getParent()
    {
        return EntityType::class;
    }

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

Use getParent() method, move all field configs to configureOptions and remove buildForm() method.

Finally.. so many hours wasted..

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.