I recommend creating a custom type for it, such as ChoiceOrTextType . To this type you add both a selection (named "selection") and a text field ("text").
use Symfony\Component\Form\AbstractType; use Symfony\Component\OptionsResolver\OptionsResolverInterface; class ChoiceOrTextType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('choice', 'choice', array( 'choices' => $options['choices'] + array('Other' => 'Other'), 'required' => false, )) ->add('text', 'text', array( 'required' => false, )) ->addModelTransformer(new ValueToChoiceOrTextTransformer($options['choices'])) ; } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setRequired(array('choices')); $resolver->setAllowedTypes(array('choices' => 'array')); } }
As you might have guessed, you also need a data transformer, which can be quite simple:
use Symfony\Component\Form\DataTransformerInterface; class ValueToChoiceOrTextTransformer implements DataTransformerInterface { private $choices; public function __construct(array $choices) { $this->choices = $choices; } public function transform($data) { if (in_array($data, $this->choices, true)) { return array('choice' => $data, 'text' => null); } return array('choice' => 'Other', 'text' => $data); } public function reverseTransform($data) { if ('Other' === $data['choice']) { return $data['text']; } return $data['choice']; } }
Now make the "menu" field a field of this type.
$builder->add('menu', new ChoiceOrTextType(), array( 'choices' => array('Option 1' => 'Option 1', 'Option 2' => 'Option 2'), 'required' => false, ));
Bernhard schussek
source share