4

As the documentation around this topic is somewhat thin, I got to a dead end.

I have two models: Job and JobAttribute. A Job has many JobAttributes and a JobAttribute has one Job:

class Job {
    /**
     * @ORM\OneToMany(targetEntity="JobAttribute", mappedBy="job_attributes")
     *
     * @var ArrayCollection
     */
    private $attributes;
}

class JobAttribute {
    /**
    * @ORM\Column(name="type", type="string", length=50)
    * 
    * @var string
    */
    private $type;

    /**
    * @ORM\ManyToOne(targetEntity="Job", inversedBy="jobs")
    */
    private $job;

Now,I have the following FormClass:

class JobType extends AbstractType {
    public function buildForm(FormBuilder $f, array $options) {
        $f->add('name', 'text');
        $f->add('attributes', 'collection', array('type' => new JobAttributeType()));
    }

    public function getName() {
        return 'job';
    }
}

class JobAttributeType extends AbstractType {
    public function buildForm(FormBuilder $f, array $options) {
        $attribute = $options['data'];
        $f->add('value', $attribute->getType());
    }

    public function getDefaultOptions(array $options) {
        return array('data_class' => 'JWF\WorkflowBundle\Entity\JobAttribute');
    }

    public function getName() {
        return 'job_attribute';
    }
}

Yes, indeed, the type property of JobAttribute contains a Form field type, eg. text.

So, as I call a FormBuilder on JobType in my Controller, $options['data'] is correctly populated with a Job-Object within JobType. But the nested JobAttributeType's $options['data'] doesn't point to an JobAttribute object. It's NULL.

What's the problem? Where is the association lost? Why is $options['data'] = NULL in nested forms? Is there a workaround in order to get dynamic field types (out of Doctrine) in a nested form?

Thanks in advance!

1 Answer 1

3

You cannot rely on $options['data'] when you build the form, as the data can (and will) be changed anytime after building. You should use event listeners instead.

$formFactory = $builder->getFormFactory();
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($formFactory) {
    $form = $event->getForm();
    $data = $event->getData();

    if ($data instanceof JobAttribute) {
        $form->add($formFactory->createNamed('value', $data->getType());
    }
});

The documentation for this can be found in the cookbook.

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

1 Comment

Hi Bernhard. What's about DataTransformer that needs form data? In PRE_SET_DATA event I can't do anything and if options['data'] has not a value during building, how can I attach the transformer? Thanks.

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.