47

I want to validate my form using server side validation only. However, if the browser supports HTML5 it validates using the HTML5 attributes added to the form by symfony2 so I need to prevent HTML5 validation.

Jon Winstanley
  • 23,010
  • 22
  • 73
  • 116
user1331787
  • 473
  • 1
  • 4
  • 4

8 Answers8

81

Just add novalidate to your <form> tag:

<form novalidate>

If you are rendering the form in TWIG, you can use following.

{{ form(form, {'attr': {'novalidate': 'novalidate'}}) }}
Josh
  • 4,894
  • 6
  • 34
  • 42
Ondrej Slinták
  • 31,386
  • 20
  • 94
  • 126
  • 1
    I got another question regarding this problem: If I want the validation on some fields and on some I want it to be turned off, I could use **'required' => false**. But there are way more fields. where I want it to be turned off. So, how can I change the default behavior **render field as required**, so I can add **'required' => true** to some fields. – insertusernamehere Jun 21 '12 at 14:09
  • Do you mean HTML5 validation or backend validation? – Ondrej Slinták Jun 21 '12 at 21:14
  • Oh sorry, didn't make that clear. I mean the HTML5-validation. Or can I somehow use an **@Assert** to say "not required" that turns off the HTML-validation for that field? – insertusernamehere Jun 22 '12 at 15:32
  • Asserts are used for entity/document validation, so don't think that would work for forms. I haven't tried Symfony 2.1 yet, but I'm pretty sure what you describe is not possible in 2.0. You will probably have to use `'required' => false` wherever you need. – Ondrej Slinták Jun 22 '12 at 16:29
  • Hey Ondrej, thanks for your reply. I guess it is that way, that you can't disable the validation globally. Many thanks for your effort. – insertusernamehere Jun 22 '12 at 17:30
21

I know its old question but with SF2.6 in FormType, you can do:

/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'attr'=>array('novalidate'=>'novalidate')
    ));
}
d3uter
  • 737
  • 9
  • 14
10

While googling for a solution to this I found one, that seems the most elegant if you want to disable html5 validation in your whole app, so I thought i'd share it here. Credits go to the author of this blog article.

The idea is to create an extension for the "form" form type like this:

<?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';
    }
}
?>

Then you just register it in your services.yml like this:

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

and you're done. All your forms automatically have a novalidate attribute now.

Symfony 3.3

As of Symfony 3.3 the configuration is slightly different, but still possible.

Slight update to the getExtendedType method to return the FormType class.

// 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;
    }
}

Plus some a minor addition of the extended_type tag, which is now required in your service declaration:

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}
naththedeveloper
  • 4,503
  • 6
  • 36
  • 44
LorenzSchaef
  • 1,523
  • 10
  • 16
  • Upvoted and updated it for Symfony 3.3 as it's slightly different now – naththedeveloper Jul 03 '17 at 10:01
  • made a bundle out of this answer to disable html5 validation in dev and test env https://packagist.org/packages/c33s/form-extra-bundle – c33s Jun 05 '18 at 23:58
  • Made a blog post of it, updated for Symfony4: https://www.strangebuzz.com/en/blog/disable-the-html5-validation-of-all-your-symfony-forms-with-a-feature-flag – COil Jul 01 '19 at 10:44
4

Alternatively if for some reason you don't want to do it in twig as in the answer above...

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

or you create your from manually with createFormBuilder then you could simply use createFormBuilder as a second parameter to define form attribute:

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

return $this->render("-----:----:----.html.twig", [
    'form'=>$form->createView()
]);
Antoine
  • 800
  • 3
  • 14
  • 29
DevWL
  • 17,345
  • 6
  • 90
  • 86
2

If you are using Symfony 3 (or 2) and want to turn off validation for a specific field only you can do this.

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

In this sample form notice the array('required' => false), you can add this to any element that you want to disable validation for without disabling validation for the others. Very useful if you want to temporarily disable only one element instead of the entire form.

Note this ONLY disables the HTML5 validation! This does not disable server side validation.

Reference: http://symfony.com/doc/current/book/forms.html#field-type-options

Joseph Astrahan
  • 8,659
  • 12
  • 83
  • 154
1

If you actually need to remove the validation attributes (if you are using a validation library want to keep all of your validation constraints in one place for example), you can overwrite the widget_attributes block in twig.

If you are already using custom form templates in app/Resources/views/form.html.twig for example (and have enabled it in your config.yml) you can just add a block for

{% 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 %}

All I have done here is remove the attributes related to validation:

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

Jon Winstanley
  • 23,010
  • 22
  • 73
  • 116
0

To disable Regex validation for specific field using formType class:

->add('foo',null,array=>('attr'=>('pattern'=>'/[^~,]/'))
Saman Mohamadi
  • 4,454
  • 4
  • 38
  • 58
0

Use form theming:

First create form theme template, e.g 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 %}

Then use that form theme in your template:

{% form_theme form with 'form/fields.html.twig' %}

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

Or, apply theme globally (app/config/config.yml):

twig:
    form_themes:
        - ':form/fields.html.twig'
JohnSmith
  • 436
  • 5
  • 17