Php Symfony2:同一页中的两个表单

Php Symfony2:同一页中的两个表单,php,forms,symfony,Php,Forms,Symfony,我在同一页上有两张表格 我的问题是,当我试图提交一个表单时,它就像试图提交页面下面的第二个表单一样 如下所示,您可以找到我的两张表格: public function createSuiviForm() { return $form = $this->createFormBuilder(null) ->add('numero', 'text', array('label' => 'N° : ', 'constra

我在同一页上有两张表格

我的问题是,当我试图提交一个表单时,它就像试图提交页面下面的第二个表单一样

如下所示,您可以找到我的两张表格:

public function createSuiviForm() {

    return $form = $this->createFormBuilder(null)
            ->add('numero', 'text', array('label' => 'N° : ',
                'constraints' => array(
                    new Assert\NotBlank(array('message' => 'XXXX')),
                    new Assert\Length(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>
我试图将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  
    }
}
这在(暂时不可用-见下文)中有很好的解释

更新
由于上面提供的链接暂时不可用,您可以看到该资源的存档。

问题是您有两个无名表单(输入名称,如
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>

{{form_小部件(更新)}
{{form_widget(form)}
{{form_errors(form)}}

我希望这将对您有所帮助。

使用命名表单是处理多个表单的可行解决方案,但它可能会变得有点混乱,特别是在动态生成表单的情况下

从Symfony 2.3开始,另一种方法是检查单击了哪个提交按钮

例如,假设每个表单都有一个名为“保存”的提交按钮:

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);
        }
    }
}

这在Symfony 3中为我实现了这一点(也适用于Symfony 2):


请看块前缀:

public function getBlockPrefix()
{
    return 'app_x_form'.$form_id;
}

显示第二个表单的html(更新)-它在源代码中的具体呈现方式,以及您在控制器中处理表单的方式可能也很有用。如何获取每个表单的数据?@Amine Harbaoui:如果您在同一操作中创建和处理表单,您应该能够使用分配的表单变量访问表单数据,例如
$suivform->getData()
。如果您在单独操作中处理表单,则必须重新创建表单,例如调用
$suivform=createsuivform();
,通过
$suivform->handleRequest($request)
处理请求,然后访问数据。链接已断开。是否有官方文档?谢谢:)你可以使用网络档案,直到它回来-我已经编辑了我的答案-或者-去
$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
    }

}
public function getBlockPrefix()
{
    return 'app_x_form'.$form_id;
}