K
K
Kinroom2017-09-15 17:26:52
symfony
Kinroom, 2017-09-15 17:26:52

Symfony Form Event Listener how to apply for collections?

I've been suffering for the third day and I can't figure out how to apply form event listeners to collections. The data changes dynamically based on user input. The form contains a collection with data in which the user fills in the fields. In order to change the data dynamically, I use the POST_SET and PRE_SUBMIT events, while the POST_SET works with a bang, but the trouble is with the events after the form is submitted.
In the PRE_SUBMIT event, I loop through all the collections of the form and get the fields of the collection that I can change. Only here the problem is that while using collections, their initialization occurs during the SUBMIT event, that is, in PRE_SUBMIT they are simply not yet in the form! And if you use the SUBMIT or POST_SUBMIT events to change, then the collection is already in the form, but it can no longer be changed, since at this stage it has already been initialized.
Therefore, it turns out a vicious circle, in PRE_SUBMIT the collection data can be changed, but they are not there yet, but in SUBMIT they are, but they can no longer be changed. Sample code for clarity:

public function preSubmit(FormEvent $event)
{
    $data = $event->getData();
    $form = $event->getForm();

    // We don`t need to change locations in add event only for update existed
    $client = $form->getConfig()->getOptions()['client'];

    $shareForms = $form->get('shares');

    foreach ($data['shares'] as $key => $share) {
        if ($share['pickUpDay'] !== null && $share['pickUpDay'] !== '') {
            $locations = $this->em->getRepository('AppBundle:Member\Location')->getLocationsByDay($client, $share['pickUpDay']);
            $this->addLocationField($shareForms->get($key), $locations);
        }
    }
}

I can't get a collection instance in preSubmit using the $shareForms->get($key) method, but I can in postSubmit, but you can't change the fields there. Maybe someone came across?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Denis, 2017-09-15
@Kinroom

<?php 

class CategoryType
{
    public function build(FormBuilderInterface $builder, array $options)
    {
        $builder->add('products', CollectionType::class, [
            'entry_type' => ProductType::class
        ]);
    }
}

class ProductType
{
    public function build(FormBuilderInterface $builder, array $options)
    {
        $builder->add('products', CollectionType::class, [
            'entry_type' => ProductType::class
        ]);

        $builder->addEventListener(FormEvents::..., function (FormEvent $event) {
            $event->getForm()->add('locations');
        });
    }
}

You don't need a listener on a collection, but on an element of the collection.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question