简体   繁体   中英

Symfony3 pass form data to collection inside collection

I have some nested forms with CollectionType and seems that the data from the constructor is not passed to the 2nd nesting level.

I simplified my form classes, just with I think's important (if you want more info jut tell me in the comments).

The bottom level form is entirely generated depending on the Activity entity class:

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

    $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) use ($options, $router) {
      $activity = $event->getData();
      dump($activity); //JUST TO TEST

      $form = $event->getForm();
      ... //$form->add of all necessary fields
    }
  }

  public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults(array(
      'data_class' => 'AppBundle\Entity\Activity',
      ...
    );
  }
}

Over the ActivityServiceCreationType I have the next form that is just a collection of the previous one:

class ActivityServiceCreationMultipleType extends AbstractType {

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

    $builder
      ->add('activities', CustomCollectionType::class, [
        'entry_type'    => ActivityServiceCreationType::class,
        'entry_options' => $options,
        'mapped'        => true,
        'allow_add'     => true,
        'show_add_link' => true,
      ])
    ;

    $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) use ($options) {
      $data = $event->getData();
      dump($data); //To test the data arriving to this form

    });
  }

  public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults(array(
      'data_class' => null,
      ...
    ));
  }
}

Then I have the "main" form, with I create from the controller:

class ActivityServiceCreationCollectionType extends AbstractType {
  public function buildForm(FormBuilderInterface $builder, array $options) {
  $builder
    ->add('selectAll', CheckboxType::class, [...])
    ...
  ;

  $builder->add('multipleActivities', CustomCollectionType::class, [
    'entry_type'    => ActivityServiceCreationMultipleType::class,
    'entry_options' => [
      "router"     => $options["router"],
      "em"         => $options['em'],
      "basePeriod" => $options['basePeriod'],
      'fit'        => $options['fit'],
      'periods'    => $options['periods'],
      'activities' => $options['activities']
    ],
    'mapped'        => true
    ])
  ;
}

From the controller I want to set the Activity objects to the ActivityServiceCreationType form, so the fields can be created. And I'm doing it like this:

$form = $this->createForm(ActivityServiceCreationCollectionType::class,
  ["multipleActivities" => ["activities" => $activities]],
  [
    "router"     => $this->get("router"),
    "em"         => $this->getEm(),
    "periods"    => $periods,
    "basePeriod" => $basePeriod,
    'fit'        => $fit
  ]);

As you can see the data for the form is:

["multipleActivities" => ["activities" => $activities]]

The results for the dumps that I put in the code is the following: For the first dump, in the ActivityServiceCreationMultipleType I get an ArrayCollection of Activities 在此输入图像描述

witch is what is expected, no problem here,

But in the second dump, in the ActivityServiceCreationType, I'm getting null . Here what I expected is an Activity entity for each one of the forms in the collection, right?

Can you tell me where I'm wrong?

-- Edited to add more info: I've been trying to know when the data is "lost" and added some code to the event in the collection type. In the ActivityServiceCreationMultipleType changed the POST_SET_DATA this way:

$builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) use ($options) {
  $data = $event->getData();
  dump($data);

  $form = $event->getForm();
  $form->get('activities')->setData($data);
});

Now the dump() in the ActivityServiceCreationMultipleType (that you see in the last code snippet) shows the array of activities. Directly the activities. And the dump() in ActivityServiceCreationType is executed 36 times (one for each activity) with null... Don't know why it seems to be passing the data to the last embedded form, but the event can not get it.

EDIT

The configurateOptions of ActivityServiceCreationCollectionType must be:

  public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults(array(
      'data_class' => null,
      'multipleActivities' => null
    );
  }

The configureOptions of ActivityServiceCreationMultipleType.

public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults(array(
      'data_class' => null,
      'entry_options' => null,
      'router" => null,
      'em" => null,
      'basePeriod" => null,
      'fit' => null,
      'periods'=>null,
      'activities' => null
    ));
  }

The configureOptions of ActivityServiceCreationType.

public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults(array(
      'data_class' => 'AppBundle\Entity\Activity',
      'entry_options' => null,
      'router" => null,
      'em" => null,
      'basePeriod" => null,
      'fit' => null,
      'periods'=>null,
      'activities' => null
    ));
  }

In conclusion, you must always indicate every external property that you want to pass to the form in configureOptions

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