我想在Symfony中创建表单时使用条件语句.
我在一般情况下使用选择小部件.如果用户选择“其他”选项,我想显示另一个文本框小部件.我想这可以在javascript中完成,但是我怎样才能将来自2个小部件的数据保存到我的实体中的同一个属性中?
到目前为止我有这个:
$builder->add('menu','choice',array( 'choices' => array('Option 1' => 'Option 1','Other' => 'Other'),'required' => false,)); //How to add text Box if choice == Other ????
我计划使用DataTransfomer,但是在2个小部件上?
解决方法
我建议为其构建自定义类型,例如ChoiceOrTextType.对于此类型,您可以添加选项(名为“choice”)和文本字段(名为“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',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')); } }
正如您已经猜到的那样,您还需要一个数据转换器,它可以非常简单:
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']; } }
现在只将“菜单”字段设为该类型的字段.
$builder->add('menu',new ChoiceOrTextType(),array( 'choices' => array('Option 1' => 'Option 1','Option 2' => 'Option 2'),));