7

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.

6
  • 8
    if you cancel, you don't want to submit, no ? why don't you use a href link and quit the page ? Commented Feb 7, 2013 at 16:48
  • Thank you for your answer. You're right, so instead of using a simble submit button, is there a possibility to use a button with href? Commented Feb 8, 2013 at 11:26
  • 1
    The better option is using a simple link. It also emphasizes what to do if you want to continue (big button) or cancel (small link). Commented Feb 8, 2013 at 13:20
  • 1
    Having a button on one side and a cancel link on the other, I prefer two buttons, and play with the colors maybe. Commented Feb 8, 2013 at 14:58
  • 1
    look at twitter.github.com/bootstrap/base-css.html#buttons, it will display links as a button if you add the right class. Useful Commented Feb 9, 2013 at 12:47

6 Answers 6

19

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

<input name="cancel" type="submit" value="Cancel" formnovalidate/>
Sign up to request clarification or add additional context in comments.

1 Comment

This should be the accepted answer: it does exactly what is desired: it disables form-validation for all fields when set on the "cancel" submit button. This works much better for many designers because you can use two submit buttons instead of one submit button and a link. It is a better semantic description of the page, too.
6

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

2 Comments

Thanks for this! Only change I made was to add style="margin-left: 10px; and btn-primary to the link class due to using Braincrafted's bootstrap.
@sarahg, this is awesome, thank you, but I had some trouble applying this to symfony 4.1, when using the bootstrap 4 theme, I've had to remove the {% extends from the template fil, don't really now why, but it works!
3

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 !

Comments

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

Comments

0

We can Easly Disable Form validation using HTML5 required attribute by formnovalidate

Comments

0

You can also do it with :

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.