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

时间:2014-06-02 12:27:55

标签: php forms symfony

我在同一页面中有两个表单。

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

如下,你可以找到我的2个表格:

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>

&#39;形式&#39;是第一个表单的变量名称 并且&#39;更新&#39;我的第二种形式。

当我尝试提交第二张表格时,我需要点击两次,最后我得到:

"This form should not contain extra fields."
And all non valid input for the remainding form.

我尝试将validation_group添加到false但无效。

我不明白为什么我收到此错误,因为我的表单根本没有嵌入

我希望你能理解......

7 个答案:

答案 0 :(得分:24)

您必须单独处理表单:

if('POST' === $request->getMethod()) {

    if ($request->request->has('form1name')) {
        // handle the first form  
    }

    if ($request->request->has('form2name')) {
        // handle the second form  
    }
}

Symfony2 Multiple Forms: Different From Embedded Forms

对此进行了详细解释

答案 1 :(得分:11)

这在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
    }

}

答案 2 :(得分:7)

问题是你有两个无名表单(输入名称如inputname而不是formname[inputname],因此当你将请求绑定到表单并且它得到验证时,它会检测到一些额外的字段(其他形式)所以它是无效的。

短期解决方案是通过表单工厂创建命名构建器,而不是:

$form = $this->createFormBuilder(null)

你应该使用:

$form = $this->get("form.factory")->createNamedBuilder("my_form_name")

长期解决方案是create your own form classes,这样您就可以将表单代码与控制器分开。

答案 3 :(得分:3)

这两个表格将被张贴。

尝试使用:

    $this->createNamedBuilder 

而不是

    $this->createFormBuilder

然后在您的控制器中,按名称找到表单:

if ($request->request->has("your form name") {
   $form->handleRequest($request);
}

答案 4 :(得分:1)

这是我在控制器上处理它们的方式:

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>

我希望这会对你有所帮助。

答案 5 :(得分:1)

使用命名表单是处理多个表单的可行解决方案,但它可能会有点混乱,特别是如果您动态生成表单。

另一种方法,如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);
        }
    }
}

答案 6 :(得分:-1)

看看blockprefix:

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