如何扩展 ChoiceType EntityType 和 DocumentType 以使用 AJAX 加载选项
在 Symfony 中,内置的 ChoiceType(以及扩展它的 EntityType 或 DocumentType)基本上使用常量选择列表。
如果你想让它与 ajax 调用一起工作,你必须改变它们以接受任何额外的额外选择。
-
如何从空选择列表开始?
在构建表单时,只需将
choices
选项设置为空的array()
:namespace AppBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; class FooType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('tag', ChoiceType::class, array('choices'=>array())); } }
因此,你将获得一个空的选择输入,没有选择。此解决方案适用于 ChoiceType 及其所有子项(EntityType,DocumentType,…)。
-
如何接受提交的新选择 :
要接受新选项,你必须在表单字段选择列表中使用它们。你可以使用 FormEvent::PRE_SUBMIT 事件根据提交的数据更改表单字段。
此示例显示如何使用基本 ChoiceType 执行此操作:
namespace AppBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; class FooType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('tag', ChoiceType::class, array('choices'=>array())) ; $builder->addEventListener( FormEvents::PRE_SUBMIT, function(FormEvent $event){ // Get the parent form $form = $event->getForm(); // Get the data for the choice field $data = $event->getData()['tag']; // Collect the new choices $choices = array(); if(is_array($data)){ foreach($data as $choice){ $choices[$choice] = $choice; } } else{ $choices[$data] = $data; } // Add the field again, with the new choices : $form->add('tag', ChoiceType::class, array('choices'=>$choices)); } ); } }
你提交的选项现在是允许的选择,Symfony ChoiceType 内置验证将不再拒绝它们。
如果你想对 ChoiceType 子项(EntityType,DocumentType,…)执行相同操作,则必须注入 entityManager 或 documentManager,并在填充新选项时执行数据转换。