Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 form validation with html5 and CANCEL button

I have a contact form on Symfony2 where I put some validators as email, minLength etc. All those fields are also set as notBlank.

Due to this, HTML5 is also validating those fields (for the email and not blank), which is fine for me.

I have a submit button:

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

The problem is that I have another submit button which is a Cancel button:

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

With this button, in my controller I am doing a redirect:

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

Now, due to the HTML5 validation, I can't redirect because the fields are empty for example.

To reslove that, I have found two solutions, but I don't like them:

  1. Disable the HTML 5 validation:

    <form novalidate>
    
  2. Use JavaScript

But as I said, I don't like those methods and I am sure that there are some nice Symfony methods to resolve that.

Any idea? Thank you very much.

like image 205
Milos Cuculovic Avatar asked Feb 07 '13 16:02

Milos Cuculovic


3 Answers

Disable the form validation exclusively for the cancel button using formnovalidate:

<input name="cancel" type="submit" value="Cancel" formnovalidate/>
like image 137
Antoine Bolvy Avatar answered Oct 15 '22 21:10

Antoine Bolvy


I see this is an older thread, but I wanted to offer an alternate solution in case others find it useful. I was unsatisfied with other answers on this topic, because I wanted to do three things:

  • Not have to do any custom form rendering in each view template (I like to just use {{ form(form) }})
  • Have the cancel button appear right next to the submit button (surprisingly tricky, since symfony by default wraps all form buttons in a div tag if you don't do custom rendering)
  • Be able to set the cancel action as an option in the controller, since the link will vary depending on whether I'm adding or editing, etc

And I wanted to do all this while applying the DRY principle. To start, I extended the base form type to allow a custom option, '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';
    }
}

And registered that form type extension in my config (using alias 'form' so that it would be available for all my forms):

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

Then I used form theming to extend the base form view (I extended the submit_widget block so that the cancel button would be next to the submit button inside the div tag):

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

And registered that form theme in my twig config so that it would apply by default to all form views:

twig:
    form_themes:
        - 'AcmeBundle:Form:fields.html.twig'

Et voila! Now for each form, if I want a cancel button, all I need to do is specify the cancel action as an option when I initialize the form in the controller:

$form = $this->createForm(new AlbumType(), $album, array(
    'cancel_action' => $this->generateUrl('album_home')
));
like image 6
sarahg Avatar answered Oct 15 '22 22:10

sarahg


i resume my comment :)

when dealing with form (HTML5 or not) and you want to quit, you don't need to submit and validate any data You just have to put a simple href link to change the page. Use your favorite css style to have the same look

Tip: you could listen to javascript event "onbeforeunload" when user has changed an input value. It alerts the user that he will quit the page

Hope it helped !

like image 3
Julien Rollin Avatar answered Oct 15 '22 22:10

Julien Rollin