简体   繁体   中英

Symfony 5.4 - EntityType multiple form field not selecting options in data

I started running into this issue after updating Symfony from 5.2 to 5.4.

I have a form field that is part of a filter UI where users select multiple statuses in this form to filter a list of data. The form is re-displayed after submission so the user sees what filters have been selected (and applied).

In the form class, the field is an EntityType with the multiple property set:

        ->add('status', EntityType::class, [
            'class' => TicketStatus::class,
            'choice_label' => 'name',
            'choice_value' => 'id',
            'data' => $this->getEntityDataMultiple($options, 'status', TicketStatus::class),
            'query_builder' => function (TicketStatusRepository $repository) {
                return $repository->createQueryBuilder(TicketStatusRepository::ALIAS)
                    ->orderBy(TicketStatusRepository::ALIAS.'.name', 'ASC');
            },
            'multiple' => true,
            'required' => false,
        ])

The data should be set by getting an array of entities of the type, which are queried for by this method that is passed in the options - an array of TicketStatus id's from the form submission:

protected function getEntityDataMultiple(array $options, string $fieldName, string $entityName): array
{
    $entityManager = $this->managerRegistry->getManagerForClass($entityName);

    $entities = [];

    if (($data = $options['data']) && is_array($data) && isset($data[$fieldName])) {
        $entityIds = $data[$fieldName];
        if (is_array($entityIds) && count($entityIds)) {
            foreach ($entityIds as $entityId) {
                $entities[$entityId] = $entityManager->find($entityName, $entityId);
            }
            //dump($entities);
        }
    }

    return $entities;
}
enter code here

If I uncomment the dump of entities in that function, it outputs an array of TicketStatuses:

^ array:1 [▼
  5 => Proxies\__CG__\App\Model\Entity\TicketStatus {#10004 ▼
    +__isInitialized__: false
    -id: 5
    -name: null
    -order: "1"
    -isActive: "1"
    -createdAt: null
    -updatedAt: null
     …2
  }

However the form field does not select the returned entit(ies), it just displays the form as if nothing had been selected. I don't think it's because it returns a proxy class; if I query for the entity name from the proxy it retuns fine. Any thoughts on what could be happening here? This same code worked in 5.2 and prior.

UPDATES 1.7.22

Still investigating the issue - an EntityType choice form has it's data property set with multiple values (representing selected options on a multi-form field) but when rendered, nothing is selected.

I ended up tracing into vendor/symfony/twig-bridge/Resources/views/Form/form_div_layout.html.twig, which is where the choice options are rendered and the select is set (or not).

{%- block choice_widget_options -%}

    {% for group_label, choice in options %}
    {%- if choice is iterable -%}
        <optgroup label="{{ choice_translation_domain is same as(false) ? group_label : group_label|trans({}, choice_translation_domain) }}">
            {% set options = choice %}
            {{- block('choice_widget_options') -}}
        </optgroup>
    {%- else -%}
{{ choice_translation_domain is same as(false)? choice.label: choice.label|trans({}, choice_translation_domain) }} {%- endif -%} {% endfor %} {%- endblock choice_widget_options -%}

The variable value is what is checked to see if this choice is selected. I added the debug and dump in the code above, and it confirms that value is just an empty array. When I revert back to 5.2, it shows an array with the values that I expect:

 <option debug array(2) { [0]=> string(1) "2" [1]=> string(1) "3" }...

I'm having a hard time determining where value is passed to this twig function. Any pointers?

You must add 'mapped' => true to your EntityType.php:

->add('status', EntityType::class, [
    'class' => TicketStatus::class,
    'choice_label' => 'name',
    'choice_value' => 'id',
    'data' => $this->getEntityDataMultiple($options, 'status', TicketStatus::class),
    'query_builder' => function (TicketStatusRepository $repository) {
        return $repository->createQueryBuilder(TicketStatusRepository::ALIAS)
            ->orderBy(TicketStatusRepository::ALIAS.'.name', 'ASC');
    },
    'multiple' => true,
    'required' => false,
    'mapped' => true
])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM