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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23994563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 17:05:08  来源:igfitidea点击:

Symfony2 : Two forms in a same page

phpformssymfony

提问by scamp

I've got two forms in a same page.

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

My problem is when I tried to submit a form, it's like it tried to submit the second form below in the page as well.

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

As follow, you can find my 2 forms :

如下,您可以找到我的 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();
}

My second form as only a submit button.

我的第二个表单只是一个提交按钮。

I passed them to my render and display them by using :

我将它们传递给我的渲染并使用以下方法显示它们:

<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' is the name of my variable to the first form and 'update' for my second form.

'form' 是我的第一个表单的变量名称和我的第二个表单的 'update' 。

When I attempted to submit my second form, I need to click twice and finally I get :

当我尝试提交我的第二个表单时,我需要单击两次,最后我得到:

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

I tried to add validation_group to false but to no avail.

我试图将validation_group 添加到false 但无济于事。

I don't understand why I got this error because my forms are not embedded at all

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

I hope you will understand...

我希望你会明白...

回答by Mick

You have to treat the forms separately:

您必须分别对待这些表格:

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

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

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

This is perfectly explained in Symfony2 Multiple Forms: Different From Embedded Forms

这在Symfony2 Multiple Forms: Different From Embedded Forms 中得到了完美的解释

回答by totas

This did the trick for me in Symfony 3 (should also work for Symfony 2):

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

}

回答by Maerlyn

The problem is that you have two nameless forms (input names like inputnameinstead of formname[inputname], and thus when you bind the request to your form and it gets validated it detects some extra fields (the other form) and so it is invalid.

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

The short-term solution is to create a named builder via the form factory, so instead of:

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

$form = $this->createFormBuilder(null)

you should use:

你应该使用:

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

The long term solution would be to create your own form classes, that way you can keep your form code separate from the controller.

长期的解决方案是创建您自己的表单类,这样您就可以将表单代码与控制器分开。

回答by Victor Odiah

The two forms will be posted.

将发布这两个表格。

Try using:

尝试使用:

    $this->createNamedBuilder 

instead of

代替

    $this->createFormBuilder

Then in your controller, locate the form by name:

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

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

回答by scamp

This is how I handle them on my controller :

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

return $this->render('SgaDemandeBundle:Demande:suivi_avancement.html.twig', 
                     array('form' => $form->createView(), 
                           ........
                           'update' => $formModification->createView()));

This is the html for the second form :

这是第二种形式的 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>

This is my twig rendered :

这是我渲染的树枝:

<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>

I hope this will help you.

我希望这能帮到您。

回答by Kal Zekdor

Using Named forms is a viable solution for handling multiple forms, but it can get a little messy, particularly if you're generating forms dynamically.

使用命名表单是处理多个表单的可行解决方案,但它可能会变得有点混乱,尤其是在动态生成表单时。

Another method, as of Symfony 2.3, is to check which submit button was clicked.

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

For example, assuming that each form has a submit button named 'save':

例如,假设每个表单都有一个名为 的提交按钮'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
    }
}

I believe this has a small amount of additional overhead as compared to the named builder method (due to multiple handleRequestcalls), but, in certain cases, it results in cleaner code. Always good to have multiple solutions to choose from. Some of the additional overhead could be alleviated via nested if/else statements, if necessary, but, unless we're talking about dozens of forms per page, the additional overhead is negligible in any case.

我相信与命名的构建器方法相比,这有少量的额外开销(由于多次handleRequest调用),但在某些情况下,它会产生更清晰的代码。有多种解决方案可供选择总是好的。如有必要,一些额外的开销可以通过嵌套的 if/else 语句来减轻,但是,除非我们每页讨论几十个表单,否则额外的开销在任何情况下都可以忽略不计。

Here's an alternate implementation using anonymous functions that minimizes code repetition:

这是使用匿名函数的替代实现,可最大限度地减少代码重复:

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

回答by cretthie

Look at the blockprefix :

查看块前缀:

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