Use conditional expression when creating a form

I would like to use a conditional statement when creating a form in Symfony.

In general, I use a selection widget. If the user selects the Other option, I would like to display an additional text window widget. I suppose this can be done in javascript, but how can I save data from two widgets to the same property in my entity?

I still have this:

$builder->add('menu', 'choice', array( 'choices' => array('Option 1' => 'Option 1', 'Other' => 'Other'), 'required' => false, )); //How to add text box if choice == Other ???? 

I planned to use DataTransfomer, but on 2 widgets

+7
source share
1 answer

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, )); 
+33
source

All Articles