Symfony2表单验证与HTML5和取消按钮

7

我在Symfony2上有一个联系表单,我设置了一些验证器,如电子邮件、最小长度等。所有这些字段也被设置为非空。

由于此原因,HTML5也会验证这些字段(对于电子邮件和非空),这对我来说很好。

我有一个提交按钮:

<input type="submit" value="Submit"/>

问题是我有另一个提交按钮,它是一个取消按钮:

<input name="cancel" type="submit" value="Cancel" />

通过这个按钮,在我的控制器中我正在进行重定向:

if( $request->get('cancel') == 'Cancel' )
    return  $this->redirect($this->generateUrl('SciForumVersion2Bundle_homepage'));

现在,由于HTML5验证,例如字段为空,我无法进行重定向。
为了解决这个问题,我找到了两个解决方案,但我不喜欢它们:
  1. Disable the HTML 5 validation:

    <form novalidate>
    
  2. Use JavaScript

但是,就像我所说的,我不喜欢那些方法,我相信有一些不错的Symfony方法来解决这个问题。

有什么想法吗?非常感谢。


8
如果您取消,您就不想提交,对吗?为什么不使用一个超链接来退出页面呢? - julien rollin
谢谢您的回答。您是正确的,所以除了使用简单的提交按钮外,是否有可能使用带有href的按钮? - Milos Cuculovic
1
更好的选择是使用一个简单的链接。它还强调了如果你想继续(大按钮)或取消(小链接)该怎么做。 - Maerlyn
1
在一侧有按钮和另一侧有取消链接时,我更喜欢两个按钮,并且可以玩弄颜色。 - Milos Cuculovic
1
请查看http://twitter.github.com/bootstrap/base-css.html#buttons,如果您添加正确的类,它将把链接显示为按钮。非常有用。 - julien rollin
谢谢@JulienRollin。你能否发表一个答案(类似于你第一条评论中提到的href),这样我就可以接受了。 - Milos Cuculovic
6个回答

19

使用 formnovalidate,仅针对取消按钮禁用表单验证:

<input name="cancel" type="submit" value="Cancel" formnovalidate/>

这应该是被接受的答案:它完全符合所需的功能:当设置在“取消”submit按钮上时,它会禁用所有字段的表单验证。对于许多设计师来说,这比使用一个submit按钮和一个链接要好得多。这也是页面更好的语义描述。 - Christopher Schultz

6

我看到这是一个较旧的帖子,但我想提供一种备选解决方案以便其他人也能从中受益。我对这个话题的其他答案不满意,因为我想做三件事:

  • 不需要在每个视图模板中进行任何自定义表单渲染(我喜欢只使用{{ form(form) }}
  • 让取消按钮出现在提交按钮旁边(令人惊讶的棘手,因为Symfony默认情况下会将所有表单按钮包装在一个div标签中,如果您没有进行自定义渲染)
  • 能够在控制器中将取消操作设置为选项,因为链接将根据我是添加还是编辑等而变化

而我想在应用DRY原则的同时完成所有这些。首先,我扩展了基本表单类型以允许自定义选项“cancel_action”:

<?php
namespace AcmeBundle\Form\Extension;

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;

class FormTypeExtension extends AbstractTypeExtension
{
    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        parent::configureOptions($resolver);

        $resolver->setDefined('cancel_action');
        $resolver->setAllowedTypes('cancel_action', 'string');
    }

    /**
     * {@inheritdoc}
     */
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        parent::buildView($view, $form, $options);

        if (isset($options['cancel_action'])) {
            $view->vars['cancel_action'] = $options['cancel_action'];
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getExtendedType()
    {
        return 'form';
    }
}

我在配置文件中注册了该表单类型扩展(使用别名“form”以便它能够为所有表单提供支持):

acme.form_type_extension:
    class: AcmeBundle\Form\Extension\FormTypeExtension
    tags:
        - {name: form.type_extension, alias: form}

然后我使用表单主题来扩展基本表单视图(我扩展了submit_widget块,以便取消按钮位于div标记内的提交按钮旁边):

{# AcmeBundle:Form:fields.html.twig #}

{% extends 'form_div_layout.html.twig' %}

{%- block submit_widget -%}
    {%- set type = type|default('submit') -%}
    {{ block('button_widget') }}
    {% if form.parent.vars.cancel_action is defined %}
        <a class="btn btn-default" href="{{ form.parent.vars.cancel_action }}" role="button">Cancel</a>
    {% endif %}
{%- endblock submit_widget -%}

我已经在twig配置中注册了该表单主题,这样它就会默认适用于所有表单视图。
twig:
    form_themes:
        - 'AcmeBundle:Form:fields.html.twig'

现在,对于每个表单,如果我想要一个取消按钮,我只需要在控制器中初始化表单时指定取消动作选项:

$form = $this->createForm(new AlbumType(), $album, array(
    'cancel_action' => $this->generateUrl('album_home')
));

谢谢!我只做了一个更改,就是由于使用Braincrafted的bootstrap,我添加了style="margin-left: 10px;btn-primary到链接类。 - geoB
@sarahg,这太棒了,谢谢你。但是我在将其应用到Symfony 4.1时遇到了一些问题,在使用Bootstrap 4主题时,我不得不从模板文件中删除{% extends。我不太清楚为什么,但它确实起作用了! - Tio

3
->add('cancel', 'submit', array(
            'label' => 'Cancel',
            'attr' => array(                       
                    'formnovalidate'=>'formnovalidate'
            ) 
    ))

3
我恢复我的评论 :)
当处理表单(无论是HTML5还是其他)并且您想要退出时,您不需要提交和验证任何数据,您只需放置一个简单的href链接以更改页面。使用您喜欢的CSS样式来实现相同的外观。
提示:当用户更改输入值时,您可以侦听JavaScript事件“onbeforeunload”。它会警告用户即将退出页面。
希望这有所帮助!

0

你也可以用以下方式实现:

<button name="cancel" type="submit" value="Cancel" formnovalidate>Cancel</button>

0

我们可以通过使用HTML5的formnovalidate属性轻松禁用表单验证。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接