Bjorn
Bjorn

Reputation: 5362

Adding a 'other, please specify' option to my ChoiceType form field in Symfony

I'm trying to create a form field with a set of choices with an extra text input which needs to be filled out if you choose 'other':

How often do you exercise?
(*) I do not exercise at the moment 
( ) Once a month
( ) Once a week
( ) Once a day
( ) Other, please specify: [             ]

Currently, I'm using a ChoiceType where I have set my choices like this:

$form->add('exercise', Type\ChoiceType::class, array(
    'label' => 'How often do you exercise?',
    'choices' => [ 'I do not excerise at the moment' => 'not', ... ],
    'expanded' => true,
    'multiple' => false,
    'required' => true,
    'constraints' => [ new Assert\NotBlank() ],
));

How do I get the 'other, please specify' option to work as expected?

Upvotes: 8

Views: 3132

Answers (1)

Kamil Adryjanek
Kamil Adryjanek

Reputation: 3338

In this case you will need to create custom form type which will be combination of ChoiceType and TextType. Nice intro to custom form types can be find id doc: http://symfony.com/doc/master/form/create_custom_field_type.html

This should be something similar to:

class ChoiceWithOtherType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // prepare passed $options

        $builder
            ->add('choice', Type\ChoiceType::class, $options)
            ->add('other', Type\TextType::class, $options)
        ;

        // this will requires also custom ModelTransformer
        $builder->addModelTransformer($transformer)

        // constraints can be added in listener
        $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
            // ... adding the constraint if needed
        });

    }

    /**
     * {@inheritdoc}
     */
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        // if needed
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        // 
    }

));

Please take a look at:

I think the best way to achieve it is to take a look at the source code of the DateTimeType.

Upvotes: 4

Related Questions