2

I need to disable / re-enable form fields depending on values of a given field. To achieve it, I use a listener on the onPreSubmit event. Then, if a field should be disabled, it is added to the form again like

$form->add('name', 'text', array("disabled" => "disabled");

This work great in one sense: if a field was enabled but should be disabled, then the result is OK. In the other sense, if a field was disabled then this field is not sent. In the listener, the field is enable but on the final result the intial value isn't there anymore.

I assume that, because the field was disabled, it wasn't sent, so Symfony considered it has a null value. From a listener on preSubmit or Submit events, if I do:

$event->getData()

Then all fields that are in the form but not in the POST data are set to null. Is there no way to activate simply the field, keeping the initial value ? Or to not consider the value of missing fields ?

3 Answers 3

5

Better later than never:)

Today i had the same problem, in conclusion you can't change options of a field using a listener because options property is private and there are only getOption and getOptions, but you can remove and add a clone of the field

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $this->buildUserForm($builder, $options);

    $builder->addEventListener(
        FormEvents::PRE_SET_DATA,
        function (FormEvent $event) {
            $form = $event->getForm();
            $user = $event->getData();
            if($user->getBirthday()){ 
                $this->disableField($form->get('birthday'));
            }
        }
    );
}

private function disableField($field){
    $parent = $field->getParent();
    $options = $field->getConfig()->getOptions();
    $name = $field->getName();
    $type = $field->getConfig()->getType()->getName();
    $parent->remove($name);
    $parent->add($name, $type, array_merge($options,['disabled' => true]));
}
Sign up to request clarification or add additional context in comments.

Comments

5

In addition to Marino Di Celemente's answer, this is a slightly adjusted disableField method for Symfony 3.2

use Symfony\Component\Form\FormInterface;
private function disableField(FormInterface $field)
{
    $parent  = $field->getParent();
    $options = $field->getConfig()->getOptions();
    $name    = $field->getName();
    $type    = get_class($field->getConfig()->getType()->getInnerType());
    $parent->remove($name);
    $parent->add($name, $type, array_merge($options, ['disabled' => true]));
}

Comments

0

Your problem looks similar to the example from Symfony's documentation on dynamic form modification. In your case, the "given field" on which values depends the disabling / re-enabling of the "name" field is equivalent to the "sport" field of Symfony's documentation, and your "name" field (more specifically the "disabled" option) is equivalent to the "position" field (more specifically the "choices" option) of Symfony's documentation.

Above, I gave the link to Symfony 2.8's documentation since it's the version you mentioned in your question, but it's not maintained anymore. If you want up-to-date information, refer to more recent doc.

Comments

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.