我在symfony2上遇到动态表单问题。我正在尝试为提交的表单生成一些字段。换句话说,用户输入一些值,提交表单,并根据这些值,我的动态字段被添加到同一个表单(显然,第二次显示)。为此,我在食谱中使用了这个例子:http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-data
所以,这是我的FormationType类
class FormationType extends AbstractType
{
private $em;
private $context;
public function __construct($em, $context) {
$this->em = $em;
$this->context = $context;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('date')
->add('type', 'choice', array(
'mapped' => false,
'choices' => Formationlist::getTypeTypes(false),
'empty_value' => false,
))
->add('cost')
->add('travelCost')
->add('maximum')
->add('location')
->add('schedule')
;
$formModifier = function(FormInterface $form, $type) {
$formationList = $this->em->getRepository('CoreBundle:FormationList')->findBy(array("year" => 1, "type" => $type));
$form->add('formationList', 'entity', array(
'label'=> 'Titre formation',
'choices' => $formationList,
'class' => 'CoreBundle:FormationList',
'property' => 'title',)
);
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event) use ($formModifier) {
$data = $event->getForm();
$type = $data->get('type')->getData();
$formModifier($event->getForm(), $type);
}
);
$builder->get('type')->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) use ($formModifier) {
$type = $event->getForm()->getData();
$formModifier($event->getForm()->getParent(), $type);
}
);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'EXAMPLE\CoreBundle\Entity\Formation'
));
}
public function getName()
{
return 'example_corebundle_formationtype';
}
}
因此,两个addEventListener工作得很好。第一次显示我的表单时,未按预期加载formModifier中的字段。我的控制器类是以下一个:
public function createAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$contextSrv = $this->get('example.service.context');
$context = $contextSrv->getContext();
$entity = new Formation();
$form = $this->createForm(new FormationType($em, $context), $entity);
$form->bind($request);
if ($form->isValid()) {
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('formation_show', array('id' => $entity->getId())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
由于我的某个动态字段不能为null,因此第一次提交表单时,它无效。因此,第二次加载FormationType。这意味着,如果填写了字段“type”,我的formModifier()函数可以加载动态字段(formationList)。直到那里,一切都运作良好,我得到了我的新领域。
但是,在表格上第二次“提交”之后......没有任何反应。页面刚刚重新加载,没有显示错误。
我用
检查了表单内容var_dump($request->request->get('example_corebundle_formationtype'));
- >每个字段(包括动态字段)都填充有效值。
我也试试这个:
foreach($form->all() as $item) {
echo $item->getName();
var_dump($item->getErrors());
}
- >这些行不显示任何错误。但是,表格永远不会有效。
var_dump($form->isValid());
- >它返回false。因此表格无效。
最后,如果我删除整个动态部分,我的表单就可以了。 我不明白什么是错的。表单没有显示错误,并且csrf标记似乎正确。我错过了什么 ?谢谢你的帮助。
答案 0 :(得分:1)
表单中某处可能存在验证错误。
而不是你对 Form :: getErrors()的复杂调用 - 这不是完全递归的,因为不会显示比第二级更深的任何字段的错误 - 你应该使用表单:: getErrorsAsString()强>
这是Symfony为您这样的开发人员创建的调试方法,试图了解验证错误在复杂表单中的位置。
如果没有显示错误,则可能是表格主题错误。创建自定义表单主题时,开发人员可能会覆盖或忘记显示字段的错误块。
问题的另一个可能来源是表格的一般显示。如果您使用 {{form_widget(form)}} 显示表单,则不会显示任何气泡到顶部表单的错误。然后确保使用 {{form_row(form)}} 。
答案 1 :(得分:1)
我知道这有点过时但在谷歌上却相当高。
getErrors()metod仅返回Form的全局错误而不返回基础字段的错误消息,在表单中使用嵌入表单时,您需要getErrors(true)或更复杂的方法。有关详细信息,请参阅:https://knpuniversity.com/blog/symfony-debugging-form-errors。
答案 2 :(得分:0)
我也遇到过这个问题几次。
在我的情况下,我发布了JSON格式的数据,所以我必须做一个具有高优先级的请求监听器,它将json数据转换为普通的POST数据,这可以在$ request->请求中找到。
$ form无效并且在帖子数据为空时也没有错误的一种情况,尝试转储$ request-> request-> all()以查看您是否有数据