DevLime
DevLime

Reputation: 1027

Symfony4 Forms - How do you conditionally disable a form field?

So what is the best way to have a form render effectively the same form over and over again, with conditionally disabled fields based on the Entity's property values?

I have an Invoice Entity and need a form for creating the invoice, and also the same form with various fields disabled at various stages of the invoicing process (generated, sent, paid etc).

I think the simplest answer is to disable them dynamically in the twig template via form_row options but surely this will affect server side validation of the form as it is not aware the field has been disabled?

What is the best way to disbale a field based on a value in the database?

EDIT 1:

Changed question from Dynamically disable a field in the twig template or seperate class for each form? to Symfony4 Forms - How do you conditionally disable a form field?

Upvotes: 3

Views: 7478

Answers (1)

DevLime
DevLime

Reputation: 1027

Thanks to @Cerad. The answer is in fact Form Events

In the form type (App\Form\InvoicesType for me), add a method call to the end of the builder:

public function buildForm(FormBuilderInterface $builder, array $options)
{

    $plus_thirty_days = new \DateTime('+28 days');

    $builder
        ->add('client', EntityType::class, array(
            'class' => Clients::class,
            'choice_label' => 'name',
            'disabled' => false,
        ) )
        // the event that will handle the conditional field
        ->addEventListener(
            FormEvents::PRE_SET_DATA,
            array($this, 'onPreSetData')
        );;
}

and then in the same class, create a public method named the same as the string in the array (onPreSetData for this example):

public function onPreSetData(FormEvent $event)
{

    // get the form
    $form = $event->getForm();

    // get the data if 'reviewing' the information
    /**
     * @var Invoices
     */
    $data = $event->getData();


    // disable field if it has been populated with a client already
    if ( $data->getClient() instanceof Clients )
        $form->add('client', EntityType::class, array(
            'class' => Clients::class,
            'choice_label' => 'name',
            'disabled' => true,
        ) );

}

From here you can update the field to be any valid FormType and specify any valid options as you would a normal form element in the From Builder and it will replace the previous one, laving it in the same original position in the form.

Upvotes: 8

Related Questions