Use a conditional statement when creating a form

后端 未结 1 621
感情败类
感情败类 2020-12-13 12:32

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

I am using a choice widget in general case. If the use

相关标签:
1条回答
  • 2020-12-13 12:48

    I recommend to build a custom type for that, for example ChoiceOrTextType. To this type you add both the choice (named "choice") and the text field (named "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 already 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 only make the "menu" field a field of that type.

    $builder->add('menu', new ChoiceOrTextType(), array(
        'choices'  => array('Option 1' => 'Option 1', 'Option 2' => 'Option 2'),
        'required' => false,
    ));
    
    0 讨论(0)
提交回复
热议问题