Artisan Développeur

Qualité, amélioration continue, agilité.

Add choices to a Symfony formType with an event listener

If you want to add (or remove) choices from a ChoiceType in your formType, this is how to do it with an event listener.
The event you will subscribe depends on the data you have and your workflow.
I had to modify a formType to allow the edition of an entity with a particular value on one field.
The field is "mode".
"myParticularMode" is a mode not available by default, I use it only under certain conditions, the entity is programmatically created, and the user is redirected to the edit form to finish to fill the data.
I don't want to allow my users to use that mode om new I don't want to allow my users to use that mode on new entity, I need it only when I edit the entities defined with this "mode".

The code take the event "POST_SET_DATA", this way I have my data, and I know the mode.
If the "mode" is myParticularMode" I add it to the choices.

Add a choice to the choices:

$builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) {
    // get the form from the event
    $form = $event->getForm();
    
    if ('myParticularMode' == $form->get('mode')->getData()) {
        // get the field options
        $options = $form->get('mode')->getConfig()->getOptions();
        // add the mode to the choices array
        $options['choices']['MY_PARTICULAR_MODE'] = 'myParticularMode_display_name';
        $form->add('mode', ChoiceType::class, $options);
    }
});

To replace all the choices and display only the one, don’t take the options, just override the choices array, and you can even disable it:

$builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) {
    // get the form from the event
    $form = $event->getForm();
    
    if ('myParticularMode' == $form->get('mode')->getData()) {
        // add the mode to the choices array
        $options['choices']['MY_PARTICULAR_MODE'] = 'myParticularMode_display_name';
        // disable the field
        $options['disabled'] = true;
        $form->add('mode', ChoiceType::class, $options);
    }
});

Enjoy 🙂

Leave a reply

Your email address will not be published.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.