I have a Symfony Form with a custom ChoiceType that needs to filter the available choices, based on the value of another field (a sibling form-type inside the same form).
I am using EasyAdmin CMS that doesn't allow its fields to pass down additional dynamic type_options to their form-types, because of it YAML configuration. And I'd like the the custom ChoiceFormType to have encapsulate the logic on how to resolve its own options.
But modifying the options based on other form data seems impossible.
- form data is
NULLinsidebuildForm(); I can access it just fromFormEvents. - inside
FormEvents::PRE_SET_DATAI cannot replace the current type with one having the modified options.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($builder, $options) {
$parent = $event->getForm()->getParent();
$parent_data = $parent-getData();
$other_field_value = $parent_data->getOtherFieldValue();
$filtered_choices = array_filter(fn($choice) => $choice !== $other_field_value);
$options['choices'] = $filtered_choices;
$parent->add($form, get_class($this), $options); // THIS FAILS
}
Trying to set the options, resolved dynamically based on the form data, fails with:
A cycle was detected. Listeners to the PRE_SET_DATA event must not call setData(). You should call setData() on the FormEvent object instead.
But the $event->setData() works just on the current FormType, not on the the whole form.