Symfony2.4 form 'This form should not contain extra fields' error
Asked Answered
H

5

19

I'm trying to build app based on REST api ang AngularJS. I've been following this tutorial http://npmasters.com/2012/11/25/Symfony2-Rest-FOSRestBundle.html but have to change some details ( depreciated methods ) and right now when I post to create new entity I get 'This form should not contain extra fields' error.

class MainController extends Controller
{
    public function indexAction(Request $request)
    {
        $form = $this->createForm(new TaskType(),null,array('action' => $this->generateUrl('post_tasks').'.json'))
                ->add('submit','submit');


        $note_form = $this->createForm(new NoteType())
                ->add('submit','submit');

        return $this->render('MyBundle:Main:index.html.twig',
                array(
                    'form'=>$form->createView(),
                    'note_form'=>$note_form->createView(),
                )
        );
    }
}

my TaskType form:

 public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder

            ->add('timeStart','datetime',array(
                'date_widget' => 'single_text',
                'time_widget' => 'single_text',
                'date_format' => 'yyyy-MM-dd',
                'data' => new \DateTime('now')
            ))

            ->add('timeStop','datetime',array(
                'date_widget' => 'single_text',
                'time_widget' => 'single_text',
                'date_format' => 'yyyy-MM-dd',
                'data' => new \DateTime('now')
            ))

            ->add('project')  
            ->add('descriptionTask')
            ->add('isCompleted',null,array('required' => false))  
            ->add('isVisible',null,array('required' => false))
        ;
    }

right now in my view I'm rendering only one form BUT I'M IN THE TEST STAGE:

{%extends 'MyBundle::layout.html.twig' %}

{%block content %}

<div ng-view></div>

{{ form(form) }}

{% endblock %}

AND this is the REST controller which is supposed to flush given entity:

public function cpostAction(Request $request)
{
 $entity = new Task();
 $form = $this->createForm(new TaskType(), $entity);
 $form->handleRequest($request);

 if ($form->isValid()) {

     $em = $this->getDoctrine()->getManager();
     $em->persist($entity);
     $em->flush();

     return $this->redirectView(
             $this->generateUrl(
                 'get_organisation',
                 array('id' => $entity->getId())
                 ),
             Codes::HTTP_CREATED
             );
 }

 return array(
     'form' => $form,
 );
}

WEIRD THING: when I put the same code from REST controller to MainController, then form is validated and new entity is being flushed, but somehow REST controller throws error...

Heim answered 11/4, 2014 at 17:24 Comment(0)
M
18

Its because when you are generating the form you are adding submit buttons but when you are validating them you are not. try:

public function cpostAction(Request $request)
{
    $entity = new Task();
    $form = $this->createForm(new TaskType(), $entity)->add('submit','submit');
    ...

The submit button is technically a field even though symfony wont map it to an entity property by default. So when you generate the form with a submit button and then submit that form the form you generate in your validation controller action needs to also have a submit button.

Maddock answered 11/4, 2014 at 18:1 Comment(2)
Many thanks for the solution. Do you know if there's a solution that doesn't require me doing this on every one of my form handlers?Kursh
Yeah instead of adding the submit after the fact add it in your TypesMaddock
M
34

If you want the validator to ignore additional fields you should try passing 'allow_extra_fields' => true as an option to the FormBuilder.

Monstrance answered 29/7, 2015 at 23:41 Comment(1)
Note: allow_extra_fields option has been added in Symfony v2.6Antenna
M
18

Its because when you are generating the form you are adding submit buttons but when you are validating them you are not. try:

public function cpostAction(Request $request)
{
    $entity = new Task();
    $form = $this->createForm(new TaskType(), $entity)->add('submit','submit');
    ...

The submit button is technically a field even though symfony wont map it to an entity property by default. So when you generate the form with a submit button and then submit that form the form you generate in your validation controller action needs to also have a submit button.

Maddock answered 11/4, 2014 at 18:1 Comment(2)
Many thanks for the solution. Do you know if there's a solution that doesn't require me doing this on every one of my form handlers?Kursh
Yeah instead of adding the submit after the fact add it in your TypesMaddock
L
5

If you wanna disable fields validation, you must add

public function setDefaultOptions(\Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'csrf_protection' => false,
        'validation_groups' => false,
    ));
}

And in buildForm method:

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->addEventListener(FormEvents::POST_SUBMIT, function ($event) {
            $event->stopPropagation();
        }, 900);
        $builder->add('field1','text')
                ->add('field2','text')
                .
                .
                .
    } 

For more details: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-dynamic-form-modification-suppressing-form-validation

Lindell answered 30/7, 2014 at 8:13 Comment(2)
Keep in mind that disabling csrf is a horrible, horrible security practice. Chances are there is always a better way of addressing the problem.Sherrod
@Sherrod But also not for restful APIGarland
T
5

Working in Symfony 4/5 in CustomFormType

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => CustomFormType::class,
        'allow_extra_fields' => true // <<<<<<<<<<<<<<<<<<<<<
    ]);
}
Technocracy answered 6/7, 2020 at 9:17 Comment(0)
H
1

If you are adding a single SubmitType button or similar, you use the solution Chausser indicated

$entity = new Task();
$form = $this->createForm(new TaskType(), $entity)->add('submit','SubmitType::class');

However, in case you are using a CollectionType and embedding a set of sub forms, you need to include 'allow_add' => true in your parameters for that type. For example, in your EntityType form builder:

$builder->add('subEntities', CollectionType::class, array(
                'entry_type' => SubEntityType::class,
                'entry_options' => array('label' => false),
                'allow_add' => true,
            ))

Make sure you do that for all levels of embedding if you have multiple levels.

Harper answered 18/10, 2018 at 20:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.