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



我在一个页面上有两个表单。

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

如下所示,你可以找到我的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;
}

相关内容

  • 没有找到相关文章

最新更新