我在一个页面上有两个表单。
我的问题是,当我试图提交一个表单时,它就像试图提交下面页面中的第二个表单一样。
如下所示,你可以找到我的2个表格:
public function createSuiviForm() {
return $form = $this->createFormBuilder(null)
->add('numero', 'text', array('label' => 'N° : ',
'constraints' => array(
new AssertNotBlank(array('message' => 'XXXX')),
new AssertLength(array('min' => 19, 'max' => 19, 'exactMessage' => 'XXX {{ limit }} XXX')))))
->add('xxxx', 'submit')
->getForm();
}
public function createModificationForm() {
return $form = $this->createFormBuilder(null)
->add('modification', 'submit', array('label' => 'XXXXXXXXXXXXXXXXXXXX'))
->getForm();
}
我的第二个表单只有一个提交按钮。
我将它们传递给我的渲染并通过使用
显示它们:<div class="well">
<form method="post" action='' {{form_enctype(form)}} >
{{ form_widget(form) }}
<input type="submit" class="btn btn-primary"/>
</form>
<div class='errors'>
{{ form_errors(form) }}
</div>
</div>
'form'是第一个form的变量名第二个表单是'update'。
当我试图提交第二个表单时,我需要点击两次,最后我得到:
"This form should not contain extra fields."
And all non valid input for the remainding form.
我尝试将validation_group添加为false,但是没有成功。
我不明白为什么我得到这个错误,因为我的窗体根本没有嵌入
您必须分别处理表单:
if('POST' === $request->getMethod()) {
if ($request->request->has('form1name')) {
// handle the first form
}
if ($request->request->has('form2name')) {
// handle the second form
}
}
这在Symfony2多表单:不同于嵌入式表单(暂时不可用-见下文)
中有很好的解释更新由于上面提供的链接暂时不可用,您可以在这里看到该资源的存档。
这在Symfony 3中对我有用(也适用于Symfony 2):
$form1 = $this->createForm(
MyFirstFormType::class
);
$form2 = $this->createForm(
MySecondFormType::class
);
if ($request->isMethod('POST')) {
$form1->handleRequest($request);
$form2->handleRequest($request);
if ($form1->isSubmitted()) {
// Handle $form1
} else if ($form2->isSubmitted()) {
// Handle $form2
}
}
问题是,你有两个无名表单(输入名称如inputname
而不是formname[inputname]
,因此,当你绑定请求到你的表单,它得到验证,它检测到一些额外的字段(另一种形式),所以它是无效的。
$form = $this->createFormBuilder(null)
应该使用:
$form = $this->get("form.factory")->createNamedBuilder("my_form_name")
长期的解决方案是创建你自己的表单类,这样你就可以把你的表单代码从控制器中分离出来。
这两张表格将被张贴。
尝试使用:
$this->createNamedBuilder
代替
$this->createFormBuilder
然后在控制器中,根据名称找到表单:
if ($request->request->has("your form name") {
$form->handleRequest($request);
}
这是我在控制器上处理它们的方式:
return $this->render('SgaDemandeBundle:Demande:suivi_avancement.html.twig',
array('form' => $form->createView(),
........
'update' => $formModification->createView()));
这是第二个表单的html:
<div class="well">
<form method="post">
<div id="form">
<div>
<button type="submit" id="form_modification"
name="form[modification]">Modification done
</button>
</div>
<input type="hidden" id="form__token" name="form[_token]"
value="fFjgI4ecd1-W70ehmLHmGH7ZmNEHAMqXlY1WrPICtK4">
</div>
</form>
</div>
这是我的树枝渲染:
<div class="well">
<form method="post" {{form_enctype(update)}} >
{{ form_widget(update) }}
</form>
</div>
<div class="well">
<form method="post" action='' {{form_enctype(form)}} >
{{ form_widget(form) }}
<input type="submit" class="btn btn-primary"/>
</form>
<div class='errors'>
{{ form_errors(form) }}
</div>
</div>
使用命名表单是处理多个表单的可行解决方案,但它可能会变得有点混乱,特别是在动态生成表单时。
另一个方法,从Symfony 2.3开始,是检查哪个提交按钮被点击了。
例如,假设每个表单都有一个名为'save'
的提交按钮:
if ('POST' == $Request->getMethod())
{
$form1->handleRequest($Request);
$form2->handleRequest($Request);
$form3->handleRequest($Request);
if ($form1->get('save')->isClicked() and $form1->isValid())
{
//Do stuff with form1
}
if ($form2->get('save')->isClicked() and $form2->isValid())
{
//Do stuff with form2
}
if ($form3->get('save')->isClicked() and $form3->isValid())
{
//Do stuff with form3
}
}
我相信,与命名的构建器方法相比,这有少量的额外开销(由于多个handleRequest
调用),但是,在某些情况下,它会产生更干净的代码。有多种解决方案可供选择总是好的。如果有必要,可以通过嵌套的if/else语句来减轻一些额外的开销,但是,除非我们讨论的是每页几十个表单,否则这些额外的开销在任何情况下都是可以忽略不计的。
下面是使用匿名函数的另一种实现,可以最大限度地减少代码重复:
$form1Action = function ($form) use (&$aVar) {
//Do stuff with form1
};
$form2Action = function ($form) use (&$anotherVar) {
//Do stuff with form2
};
$form3Action = function ($form) use (&$yetAnotherVar) {
//Do stuff with form3
};
$forms = [$form1 => $form1Action,
$form2 => $form2Action,
$form3 => $form3Action];
if ('POST' == $Request->getMethod())
{
foreach ($forms as $form => $action)
{
$form->handleRequest($Request);
if ($form->get('save')->isClicked() and $form->isValid())
{
$action($form);
}
}
}
查看blockprefix:
public function getBlockPrefix()
{
return 'app_x_form'.$form_id;
}