0

Starting from the example in the symfony cookbook about dynamic form generation (link to doc)

class SportMeetupType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('sport', 'entity', array(...))
        ;

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function(FormEvent $event) {
                $form = $event->getForm();

                // this would be your entity, i.e. SportMeetup
                $data = $event->getData();

                $positions = $data->getSport()->getAvailablePositions();

                $form->add('position', 'entity', array('choices' => $positions));
            }
        );
    }
}

I reproduced this code with a difference, I embed this form in a parent form (called for the exemple SportPlayerType).

SportPlayerType is mapped on entity SportPlayer which contains a couple of attributes : $name and $meetup, a string and a SportMeetup.

My problem is in the lambda function, parameter of the addEventListener :

  • $event->getForm() returns the child form SportMeetupType
  • $event->getData() returns the parent mapped entity SportPlayer

As a result, $form->add('position') throw an error because the FormBuilder cannot match position field on entity SportPlayer.

How could I force matching between SportMeetupType and entity SportMeetup when SportMeetupType in an embed form?

3
  • I usually just use a subscriber class so I'm not sure if this is the problem. The listener will get called twice. You should have a if !$data) return in there. And you might consider making a subscriber class though it really should not make any difference. Commented Nov 18, 2013 at 19:35
  • You should be able to access the embedded form. $form->get('sport'), assuming that it what this form is doing. Commented Nov 18, 2013 at 20:31
  • @Flosculus I already tried this solution, but the problem is not the form, it is the entity accessed from $event->getData() Commented Nov 18, 2013 at 20:51

1 Answer 1

1

We'll there is a reason the event is called PRE_SET_DATA ...

Namely the event gets fired before the submitted data is set.

Therefore you can't access ...

$event->getData()->getSport();

... in the listener as long as you don't provide a new Sport() object or an existing entity when creating the form i.e. in a controller like this:

$entity = new Sport(); // ... or get the entity from db
$form = $this->createForm(new SportMeetupType(), $entity);

Just use the POST_SET_DATA event and the data will be available.

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

5 Comments

I tried this : $player = new SportPlayer(); $player->setSportMeetup(new SportMeetup()); $form = $this->createForm(new SportPlayerType(), $player); But the result is the same on PRE_SET_DATA and POST_SET_DATA events : Neither the property "position" nor one of the methods "getPosition()", "isPosition()", "hasPosition()", "__get()" or "__call()" exist and have public access in class "SportPlayer"
Well can you confirm that your SportPlayer class indeed does have a method getPosition() that returns the $position property ?
No. SportPlayer have a method getSportMeetup() returning a SportMeetup. SportMeetup have a method getposition(). This is the problem, data in the Event is a SportPlayer, but the form in the Event is mapped on the SportMeetup.
Then call $event->getData->getSportMeetup()->getPosition() ... and make sure you have $this->sportMeetup = new SportMeetup(); in the __construct() method of your SportPlayer class!
The error occurs when, in the EventListener, I add a new field in my form $form->add('position'). I know how to access to the position threw the SportMeetup getter, but how can I tell symfony to do the same on form creation ? Maybe it will be clearer if I tell you I tried, as a solution, to set the property_path of the position field to 'sportMeetup/position'...

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.