Symfony2:在处理之前预览表单数据的好模式是什么?

时间:2013-11-02 13:40:52

标签: forms symfony

我在我正在开发的应用程序中遇到了一个常见问题,有三个用例描述为:

  

对象创建表单后面必须跟一个预览页面   对象以最终状态显示,并带有一个完成按钮的按钮   创建,以及返回并使用表单修改它的按钮。

我已经有了一个典型的基础创建流程。一个newAction,它使用表单呈现newObject模板,该模板将数据发送到检查数据的createAction,创建对象,并重定向到showObject操作。

我的粗略想法是: newAction呈现newObject模板,其表单将数据发送到createAction,就像之前一样。这个createAction呈现一个带有两个按钮的previewObject模板,它将表单发送到createAction angain,在那里我可以检查哪个按钮被按下了,我可以决定再次显示带有对象数据的表单,或者完成cration流程并重定向到showObject动作。

我的问题是:

  1. 根据模板的不同,有三个不同的按钮(预览,编辑和创建)应显示或隐藏(新建,预览)。
  2. 除按钮外,必须全部隐藏previewObject模板中的表单。 “预览”对象是否必须作为隐藏表单传递,还是有其他方式我没有看到?
  3. 我需要多种表单来实现此功能吗?我正在尝试用一种形式和两种动作来思考解决方案,但我不确定它是否足够。

    这是一个常见的用例,但我无法在线查找示例。

    任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

你的问题让我感到好奇,我尝试了一些不同的东西。想出了一种有趣的方法来使用控制器中的createFormBuilder使用单个表单和单个操作来处​​理它,但我无法找到将createFormFormType一起使用的方法,因为调用$form = $this->createForm(new NewsletterSignupType());后,您无法在控制器中操作表单。

感觉有点hacky但是在这里,希望如果没有别的,它会给你一些想法。

class DemoController extends Controller
{
    /**
     * @Route("/", name="newsletter_signup")
     * @Template()
     */
    public function newsletterSignupAction(Request $request)
    {
        $form = $this->getNewsletterSignupForm();

        $form->handleRequest($request);

        if ($form->isValid()) {
            $newButton    = $form->get('new');
            $editButton   = $form->get('edit');
            $createButton = $form->get('create');

            if ($newButton->isClicked()) {
                $form = $this->getNewsletterSignupForm($form->getData(), true);
            }

            if ($editButton->isClicked()) {
                /**
                 * We don't have to do anything here because we are just
                 * returning the original form with the submitted data attached
                 */
            }

            if ($createButton->isClicked()) {
                // User verified data and clicked "Create"
                $response = 'Thank you for signing up!';

                return new Response($response);
            }
        }

        return array(
            'form' => $form->createView()
        );
    }

    /**
     * Handle creating the form and setting fields / buttons and data
     */
    protected function getNewsletterSignupForm($data = null, $previewMode = false)
    {
        $actionUrl = $this->generateUrl('newsletter_signup');

        $formBuilder             = $this->createFormBuilder($data);
        $fieldAttributes         = [];
        $newButtonAttributes     = [];
        $previewButtonAttributes = [];

        if ($previewMode) {
            $fieldAttributes['read_only'] = true;
            $newButtonAttributes['attr']  = ['hidden' => true];
        } else {
            $previewButtonAttributes['attr'] = ['hidden' => true];
        }

        $formBuilder->add('name', 'text', $fieldAttributes)
                    ->add('email_address', 'email', $fieldAttributes)
                    ->add('new', 'submit', $newButtonAttributes)
                    ->add('edit', 'submit', $previewButtonAttributes)
                    ->add('create', 'submit', $previewButtonAttributes);

        $formBuilder->setAction($actionUrl);

        $form = $formBuilder->getForm();

        return $form;
    }
}

查看代码:

{# Acme:DemoBundle:newsletterSignup.html.twig #}

{% extends 'AcmeDemoBundle::layout.html.twig' %}

{% block content %}
    {{ form(form) }}
{% endblock content %}