7

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 つのウィジェットで??

4

1 に答える 1

33

そのためのカスタム タイプを作成することをお勧めし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', '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'),
    'required' => false,
));
于 2012-07-25T18:16:32.933 に答える