如何处理多个页面上使用的表单?

时间:2011-08-09 13:45:03

标签: php symfony

我有一个我需要在多个页面上使用的表单:

控制器

$emailForm = $this->get('form.factory')->createNamedBuilder('form', 'email_form')
    ->add('email', 'email')
    ->add('subject', 'text')
    ->add('body', 'textarea')
    ->getForm();

$request = $this->get('request');

if ($request->getMethod() == 'POST' && $request->request->has('email_form') ) {
    $emailForm->bindRequest($request);

    if ($emailForm->isValid()) {

        // do stuff ...

        $this->get('session')->setFlash('email_sent', "Woey, mail sent successfully!");

        // Redirect on the same url to prevent double posts
        return $this->redirect($this->generateUrl($this->getRequest()->attributes->get('_route')));
    }
}

return $this->render('Bundle:Form:index.html.twig', array('email_form' => $emailForm->createView()));

模板

{% if app.session.getFlash('email_sent') %}
    <p>{{ app.session.getFlash('email_sent') }}</p>
{% endif %}

<form action="{{ path(app.request.attributes.get('_route')) }}" method="post" {{ form_enctype(email_form) }}>
    {{ form_widget(email_form) }}

    <p><input type="submit" class="submit" value="Send" /></p>
</form>

它实际上只是标准的Symfony2形式,几乎与教程一样。

我无法想象如何在不重复自己(太多)的情况下在多个页面上(在多个控制器操作中)有效地使用它。到目前为止我试过了:

  • 将逻辑放入Base控制器,它是我想拥有此表单的每个控制器的父控制器。这种方法存在两个问题:
    • 我无法想象如何正确地重定向到同一页面
    • 我不得不在每个动作中调用父方法,这不是一个真正的问题,但我想必须有一些更优雅的方式
  • 在树枝中使用embedded controllers渲染控制器。但是,我无法想象how to redirect properly

那么,这种形式的常用方法是什么?

修改

我正在寻找无脚本解决方案。

3 个答案:

答案 0 :(得分:2)

我最终在我需要的每个页面上使用嵌入式控制器,发布到不同的URL并使用referrer保存cookie。然后我验证表单,保存带结果的cookie,重定向回引用并呈现结果(错误,谢谢消息......)。当您处理必须考虑禁用Javascript的场景时,这似乎是最佳选择。对于用户使用AJAX发布的情况,您可以使用简单条件轻松禁用冗余cookie / flash会话的创建。

答案 1 :(得分:1)

Symfony2 Forms教程也针对您的场景,请参阅Creating Form ClassesDocs部分,其中“您将学习如何在独立的类中构建表单,建议您的表单可重用” (同上)。

答案 2 :(得分:1)

您应该通过ajax帖子提交数据。

在控制器中做你的事:p 然后在树枝模板中渲染表单,而不扩展布局。 (就像目前一样)

然后在任何视图中你只需替换结果:$('#formDiv')。html(htmlReceivedBack);

我发现用新渲染的html再次替换整个html div是最简单的;您很可能会显示成功消息或某些表单错误。

这样,用户无需仅仅为了发送消息/反馈而更改页面。