Symfony2禁用HTML5表单验证

47

我希望只使用服务器端验证来验证我的表单,但是如果浏览器支持HTML5,则会使用Symfony2添加到表单中的HTML5属性进行验证,因此我需要禁止HTML5验证。

8个回答

81

只需在您的<form>标签中添加novalidate即可:

<form novalidate>

如果你正在使用TWIG渲染表单,可以使用以下代码。

{{ form(form, {'attr': {'novalidate': 'novalidate'}}) }}

1
我有另一个关于这个问题的问题:如果我想在某些字段上进行验证,而在某些字段上我想关闭验证,我可以使用 'required' => false。但是有更多的字段需要关闭验证。那么,我该如何更改默认行为 将字段呈现为必填项,以便我可以将 'required' => true 添加到某些字段中。 - insertusernamehere
你是指HTML5验证还是后端验证? - Ondrej Slinták
哦,抱歉,我没有表达清楚。我的意思是HTML5验证。或者我可以使用**@Assert**来表示“不需要”,从而关闭该字段的HTML验证吗? - insertusernamehere
断言用于实体/文档验证,因此不要认为它适用于表单。我还没有尝试过Symfony 2.1,但我非常确定您描述的在2.0中是不可能的。您可能需要在需要的地方使用“'required' => false”。 - Ondrej Slinták
嗨,Ondrej,谢谢您的回复。我想您不能全局禁用验证。非常感谢您的努力。 - insertusernamehere

21

我知道这是一个老问题,但在SF2.6中的FormType中,您可以这样做:

/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'attr'=>array('novalidate'=>'novalidate')
    ));
}

谢谢,正是我所需要的。我给你一个赞 +1 :) - Eddie Jaoude
谢谢。这是最好的。 - Mohammad Zare Moghadam
2
在Symfony 2.7中,OptionsResolverInterface已被弃用。 - Thomas Shelby
请使用public function configureOptions(OptionsResolver $resolver)方法来替代@PawełBrzoski和setDefaultOptions方法。 - Ivan Yarych
在Symfony 3.3中,使用setDefaultOptions(OptionsResolver $resolver)同样有效! - goulashsoup

10
在谷歌搜索解决方案时,我找到了一个看起来最优雅的方法,如果您想在整个应用程序中禁用HTML5验证,那么我想在这里分享它。 鸣谢这篇博客文章的作者。
思路是创建一个 "form" 表单类型的扩展,如下所示:
<?php
// src/AppBundle/Form/Extension/NoValidateExtension.php

namespace AppBundle\Form\Extension;

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


class NoValidateExtension extends AbstractTypeExtension
{
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['attr'] = array_merge($view->vars['attr'], [
            'novalidate' => 'novalidate',
        ]);
    }

    public function getExtendedType()
    {
        return 'form';
    }
}
?>

然后您只需要像这样在services.yml中注册它:

app.no_validation_form_extension:
    class: AppBundle\Form\Extension\NoValidateExtension
    tags:
        - {name: form.type_extension, alias: form}

完成了。现在你的所有表单都自动具有novalidate属性。

Symfony 3.3

从Symfony 3.3开始,配置略有不同,但仍然可行。

getExtendedType方法有轻微更新,返回 FormType 类。

// src/AppBundle/Form/Extension/NoValidateExtension.php

namespace AppBundle\Form\Extension;

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\Extension\Core\Type\FormType;

class NoValidateExtension extends AbstractTypeExtension
{
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['attr'] = array_merge($view->vars['attr'], [
            'novalidate' => 'novalidate',
        ]);
    }

    public function getExtendedType()
    {
        return FormType::class;
    }
}

除此之外,你的服务声明中现在还需要一个extended_type标签的小改动:

app.no_validation_form_extension:
    class: AppBundle\Form\Extension\NoValidateExtension
    tags:
        - {name: form.type_extension, alias: form, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType}

已点赞并更新为Symfony 3.3,因为现在有些不同。 - naththedeveloper
使用此答案在开发和测试环境中禁用HTML5验证,从而轻松解决问题。https://packagist.org/packages/c33s/form-extra-bundle - c33s
已发布一篇博客文章,更新适用于Symfony4:https://www.strangebuzz.com/en/blog/disable-the-html5-validation-of-all-your-symfony-forms-with-a-feature-flag - COil

4

如果你不想使用上面回答中的twig,或者由于某些原因无法使用twig...

{{ form(form, {'attr': {'novalidate': 'novalidate'}}) }}

或者你可以手动创建createFormBuilder表单,然后使用createFormBuilder作为第二个参数来定义表单属性:

//someAction
$form = $this->createFormBuilder(null, ['attr'=>['novalidate'=>'novalidate']])
->add(...)
->add(...)
->add(...)
->getFrom();

return $this->render("-----:----:----.html.twig", [
    'form'=>$form->createView()
]);

2
如果你正在使用Symfony 3(或2)并且只想关闭特定字段的验证,你可以这样做。
$form = $this->createFormBuilder($task)
            ->add('task', TextType::class, array('required' => false))
            ->add('dueDate', DateType::class)
            ->add('save', SubmitType::class, array('label' => 'Create Task'))
            ->add('saveAndAdd', SubmitType::class, array('label' => 'Save and Add'))
            ->getForm();

在这个示例表单中,请注意array('required' => false),您可以将其添加到任何要禁用验证但不禁用其他元素验证的元素中。如果您只想临时禁用一个元素而不是整个表单,则非常有用。 请注意,这仅禁用HTML5验证!这不会禁用服务器端验证。
参考资料:http://symfony.com/doc/current/book/forms.html#field-type-options

1
如果您确实需要删除验证属性(例如,如果您正在使用验证库并希望将所有验证约束都保留在一个地方),则可以在twig中覆盖widget_attributes块以删除它们。
如果您已经在app / Resources / views / form.html.twig中使用自定义表单模板(并在config.yml中启用了它),则只需添加一个块即可。
{% block widget_attributes %}
{% spaceless %}
    id="{{ id }}" name="{{ full_name }}"{% if read_only %} readonly="readonly"{% endif %}{% if disabled %} disabled="disabled"{% endif %}
    {% for attrname, attrvalue in attr %}{% if attrname in ['placeholder', 'title'] %}{{ attrname }}="{{ attrvalue|trans({}, translation_domain) }}" {% else %}{{ attrname }}="{{ attrvalue }}" {% endif %}{% endfor %}
{% endspaceless %}
{% endblock widget_attributes %}

我在这里所做的只是移除与验证相关的属性:

{% if required %} required="required"{% endif %}{% if max_length %} maxlength="{{ max_length }}"{% endif %}{% if pattern %} pattern="{{ pattern }}"{% endif %}


0

使用表单主题

首先创建表单主题模板,例如app/Resources/views/form/fields.html.twig:

{% extends 'form_div_layout.html.twig' %}{# or some other base layout #}

{% block form_start %}
    {% if attr.novalidate is not defined %}
        {% set attr = attr|merge({'novalidate':'novalidate'}) %}
    {% endif %}
    {{ parent() }}
{% endblock %}

然后在您的模板中使用该表单主题:
{% form_theme form with 'form/fields.html.twig' %}

{{ form_start(form) }} <-- now renders with novalidate attribute
...
{{ form_end(form) }}

或者,在全局应用主题(app/config/config.yml):

twig:
    form_themes:
        - ':form/fields.html.twig'

0

使用formType类禁用特定字段的Regex验证:

->add('foo',null,array=>('attr'=>('pattern'=>'/[^~,]/'))

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