Dependent Form Fields
Unleash the power of form events, thanks to LiveComponent
and DynamicForms
.
// ... use statements hidden - click to show
#[AsLiveComponent]
class MealPlanner extends AbstractController
{
use ComponentWithFormTrait;
use DefaultActionTrait;
protected function instantiateForm(): FormInterface
{
return $this->createForm(MealPlannerForm::class);
}
}
{# See src/Form/MealPlannerForm.php for the form magic #}
<div
{{ attributes }}
>
{{ form_start(form) }}
{{ form_row(form.meal) }}
{{ form_row(form.mainFood) }}
{% if form.pizzaSize is defined %}
{{ form_row(form.pizzaSize) }}
{% endif %}
{{ form_end(form) }}
</div>
// ... use statements hidden - click to show
class MealPlannerForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
/**
* Install DynamicFormBuilder:.
*
* composer require symfonycasts/dynamic-forms
*/
$builder = new DynamicFormBuilder($builder);
$builder
->add('meal', EnumType::class, [
'class' => Meal::class,
'choice_label' => fn (Meal $meal): string => $meal->getReadable(),
'placeholder' => 'Which meal is it?',
'autocomplete' => true,
])
// see: https://github.com/SymfonyCasts/dynamic-forms
->addDependent('mainFood', 'meal', function (DependentField $field, ?Meal $meal) {
$field->add(EnumType::class, [
'class' => Food::class,
'placeholder' => null === $meal ? 'Select a meal first' : \sprintf('What\'s for %s?', $meal->getReadable()),
'choices' => $meal?->getFoodChoices(),
'choice_label' => fn (Food $food): string => $food->getReadable(),
'disabled' => null === $meal,
'autocomplete' => true,
]);
})
->addDependent('pizzaSize', 'mainFood', function (DependentField $field, ?Food $food) {
if (Food::Pizza !== $food) {
return;
}
$field->add(EnumType::class, [
'class' => PizzaSize::class,
'placeholder' => 'What size pizza?',
'choice_label' => fn (PizzaSize $pizzaSize): string => $pizzaSize->getReadable(),
'required' => true,
'autocomplete' => true,
]);
})
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(['data_class' => MealPlan::class]);
}
}
Author
weaverryan
Published
2022-06-17