2012-01-06 9 views
3

私はSymfonyフォームにchoice型の要素を持つコレクションフィールドを持っています。各要素は異なるリスト選択を持つ必要があります。これをSymfony2でどうやって手配できますか? choicesオプションを使用することはできません。すべての要素に同じ選択肢があるからです。私はchoice_listオプションのリストを生成することができるオブジェクトを取るオプションを見ましたが、どのようにコレクションのさまざまな要素に対して異なる選択肢を生成するか分かりません。Symfony2形式のコレクションフィールドを別の選択肢で使用することはできますか?

これに対処する方法はありますか?

+0

具体的なケースについて教えてください。達成しようとしていることは何ですか?私はあなたが何を意味しているかをかなり理解していませんでした。 –

+0

上記のように、私はあなたが何を意味するかはよく分かりません。フォーム内で__constructを使用して、処理している 'データオブジェクト'であるオブジェクトに応じてフォームに選択肢を渡すことができます。 –

答えて

3

私は、あなたがフォームイベント:http://symfony.com/doc/current/cookbook/form/dynamic_form_generation.htmlが必要だと思います。

コレクションのデフォルトの方法を変更します。

メインフォームは単純です:

namespace Acme\Bundle\AcmeBundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilder; 

use Acme\Bundle\AcmeBundle\Form\DescriptorDumpFieldsType; 

class TranscodingType extends AbstractType 
{ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $builder->add('descriptorDumpFields', 'collection', array('type' => new DescriptorDumpFieldsType())); 
    } 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class' => 'Acme\Bundle\AcmeBundle\Entity\Descriptor', 
     ); 
    } 

    public function getName() 
    { 
     return 'descriptor'; 
    } 
} 

サブフォームのコレクションを持つ単純なフォーム。

2番目は、フォームの作成を処理するフォームのサブスクライバを使用します。 (フォームイベントを使用)

したがって、最初のフォームは正常に作成され、動的に作成される多くのDescriptorDumpFieldsTypeを追加します。

namespace Acme\Bundle\AcmeBundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilder; 
use Symfony\Component\Form\FormTypeInterface; 

use Acme\Bundle\AcmeBundle\Form\EventListener\TranscodingSubscriber; 

class DescriptorDumpFieldsType extends AbstractType 
{ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $subscriber = new TranscodingSubscriber($builder->getFormFactory()); 
     $builder->addEventSubscriber($subscriber); 
    } 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class' => 'Acme\Bundle\AcmeBundle\Entity\DescriptorDumpField', 
     ); 
    } 

    public function getName() 
    { 
     return 'desc_dump_field'; 
    } 
} 

フォーム加入者:

namespace Acme\Bundle\AcmeBundle\Form\EventListener; 

use Symfony\Component\Form\Event\DataEvent; 
use Symfony\Component\Form\FormFactoryInterface; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\Form\FormEvents; 

use Acme\Bundle\AcmeBundle\Entity\DumpField; 

use Acme\Bundle\AcmeBundle\Form\Transcoding\DataTransformer\JsonToHumanDateTransformer; 

class TranscodingSubscriber implements EventSubscriberInterface 
{ 
    private $factory; 

    public function __construct(FormFactoryInterface $factory) 
    { 
     $this->factory = $factory; 
    } 

    public static function getSubscribedEvents() 
    { 
     return array(FormEvents::SET_DATA => 'setData'); 
    } 

    public function setData(DataEvent $event) 
    { 
     $data = $event->getData(); 
     $form = $event->getForm(); 

     if (!is_null($data)) { 
      $this->buildForm($data, $form);    
     } 
    } 

    protected function buildForm($data, $form) 
    { 
     switch ($data->getDumpField()->getType()) { 
      case DumpField::TYPE_ENUM: 
       $type = 'enum'.ucfirst($data->getDumpField()->getKey()); 
       $class = 'dump_field_'.strtolower($data->getDumpField()->getKey()); 
       $form->add($this->factory->createNamed('collection', 'transcodings', null, array('required' => false, 'type' => $type, 'label' => $data->getDumpField()->getKey(), 'attr' => array('class' => $class)))); 
       break; 
      case DumpField::TYPE_DATE: 
       $transformer = new JsonToHumanDateTransformer(); 
       $class = 'dump_field_'.strtolower($data->getDumpField()->getKey()); 
       $builder = $this->factory->createNamedBuilder('human_date', 'params', null, array('label' => $data->getDumpField()->getKey(), 'attr' => array('class' => $class))); 
       $builder->prependNormTransformer($transformer); 
       $form->add($builder->getForm()); 
       break; 
     } 
    } 
} 

だから、あなたが望む方法、buildFormでコレクションの各サブフォームをカスタマイズすることができます。

+0

トレインありがとう、私のために働いた。 – ninsky

関連する問題