I have a Symfony2 Form with two layered dynamic fields. The first Layer is no problem implementing the documented way with form events: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms
But then comes a third field, which depends on the second field, which is already a dynamic field.
To demonstrate the problem, here is my stripped code:
<?php
class ServiceeventType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('park', 'entity', array(
'class' => 'AppBundle:Park',
'property' => 'identifyingName',
'label' => 'Park',
'required' => true,
'invalid_message' => 'Choose a Park',
'placeholder' => 'Please choose',
))
// just a placeholder for the $builder->get('facility')->addEventListener to have something to bind to
// I'm aware, that this is just a symptom of my problem
->add('facility', 'choice', array(
'choices' => array(),
'expanded' => true,
'multiple' => false,
'label' => 'Facility',
'required' => false,
'invalid_message' => 'Choose a Park first',
'placeholder' => 'Please choose a Park first',
))
// other fields
;
$formModifierPark = function (FormInterface $form, Park $park = null) {
// overwrite the facility field with the desired entity type
$form->add('facility', 'entity', array(
'class' => 'AppBundle:Facility',
'property' => 'identifyingName',
'choices' => null === $park ? array() : $park->getFacilities(),
'label' => 'Facility',
'required' => true,
'invalid_message' => 'Choose a Facility',
'placeholder' => null === $park ? 'Please choose a Park first' : 'Please choose',
));
};
$formModifierFacility = function (FormInterface $form, Facility $facility = null) {
$form->add('facilityStatuscode', 'entity', array(
'class' => 'AppBundle:FacilityStatuscode',
'property' => 'identifyingName',
'choices' => null === $facility ? array() : $facility->getFacilityStatuscodeType()->getFacilityStatuscodes(),
'label' => 'Statuscode',
'required' => null === $facility ? false : true,
'invalid_message' => 'Choose a Statuscode',
'placeholder' => null === $facility ? 'Please choose a Facility first' : 'Please choose',
));
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifierPark) {
$formModifierPark($event->getForm(), $event->getData()->getPark());
}
);
$builder->get('park')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifierPark) {
$formModifierPark($event->getForm()->getParent(), $event->getForm()->getData());
}
);
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifierFacility) {
$formModifierFacility($event->getForm(), $event->getData()->getFacility());
}
);
$builder->get('facility')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifierFacility) {
$formModifierFacility($event->getForm()->getParent(), $event->getForm()->getData());
}
);
}
// more code
}
The problem is now:
The event-listener set with $builder->get('facility')->addEventListener(FormEvents::POST_SUBMIT,…
gets lost at the moment, the facility-field is overwritten by the other event-listener.
I tried several workarounds, but it turns out, that form field options cannot be overridden and form later added fields don't accept new event listeners, once the builder is ready (i.e. when added inside an event listener).
I really have to solve this. Am I missing something? Is Symfony2's Form engine not able to handle two layered dynamic form field dependencies?
Any suggestions?
See Question&Answers more detail:
os