私は、あなたがフォームイベント: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でコレクションの各サブフォームをカスタマイズすることができます。
具体的なケースについて教えてください。達成しようとしていることは何ですか?私はあなたが何を意味しているかをかなり理解していませんでした。 –
上記のように、私はあなたが何を意味するかはよく分かりません。フォーム内で__constructを使用して、処理している 'データオブジェクト'であるオブジェクトに応じてフォームに選択肢を渡すことができます。 –