Home » Php » php – Symfony2 disable HTML5 form validation

php – Symfony2 disable HTML5 form validation

Posted by: admin April 23, 2020 Leave a comment

Questions:

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.

How to&Answers:

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'}}) }}

Answer:

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

Answer:

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}

Answer:

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

Answer:

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

Answer:

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

Answer:

To disable Regex validation for specific field using formType class:

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

Answer:

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'