6

I am submitting a form and handling it in the Sylius ResourceController which submits the form and validates it.

This is the form in situ:

<tr>
   <form method="post" action="{{ path('backend_course_row_update', {
 'courseeId' : course.id, 'id' : row.id }) }}" novalidate>
     {{ form_widget(form.channel) }}
     {{ form_widget(form.name) }}
     {% for size in form.sizes %}
        {{ form_row(size) }}
     {% endfor %}
     {{ form_row(form._token) }}
     <td align="right" style="width: 140px;">
         <button class="btn btn-primary" type="submit">
            <i class="glyphicon glyphicon-save"></i>Save
         </button>
     </td>
  </form>
</tr>

The "form" here is a CourseGuideRowType, which looks like this:

/**
 * {@inheritdoc}
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('channel', 'channel_choice', array(
            'required'    => false
        ))
        ->add('name', 'text')
        ->add('sizes', 'course_guide_row_sizes', array('numColumns' => $options['numColumns']))
    ;
}

CourseGuideRowSizesType then looks like this:

/**
 * {@inheritdoc}
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    for ($i = 0; $i < $options['numColumns']; $i++) {
        $builder->add($i, 'text', array('required' => 'false'));
    }
    $builder->addEventListener(
        FormEvents::PRE_SUBMIT,
        function (FormEvent $event) use ($options) {
            $form = $event->getForm();
            for ($i = 0; $i < $options['numColumns']; $i++) {
                if (empty($form->get($i)->getData())) {
                    $form->remove($i, 'text');
                }
            }
        }
    );
}

However, when I submit the form and dump out the errors like this:

$form->submit($request, !$request->isMethod('PATCH'))->getErrors()

I get:

"This form should not contain extra fields."
      #messageParameters: array:1 [▼
        "{{ extra_fields }}" => "0", "1", "2", "3", "4", "5"
      ]
        -extraData: array:6 [▼
          0 => "36"
          1 => "38"
          2 => "40"
          3 => "42"
          4 => "44"
          5 => "46"
        ]

The "extra data" is the "sizes" fields.

Am I doing something blatantly wrong here?

EDIT June 2017: You can now use 'allow_extra_fields' to suppress this error. http://symfony.com/doc/current/reference/forms/types/form.html#allow-extra-fields

crmpicco
  • 14,513
  • 22
  • 113
  • 191
  • 1
    Normally the error is thrown when user submitted data has more inputs than are defined in the form. Symfony has a built in type which already does what you are trying to do manually: http://symfony.com/doc/current/reference/forms/types/collection.html . – Karolis Feb 25 '16 at 18:59
  • 2
    Also not the best solution, but you can also allow extra fields by setting `'allow_extra_fields' => true` on option resolver. – nakashu Feb 25 '16 at 19:46
  • 1
    Note: allow_extra_fields option has been added in Symfony v2.6 – Munir Jun 20 '17 at 14:33
  • @Munir Yes, you're right. Thanks for the comment. – crmpicco Jun 21 '17 at 10:10

1 Answers1

10

The error is thrown because you are defining each size as a form_row, e.g. :

{% for size in form.sizes %}
    {{ form_row(size) }}  // Extra field defined here
 {% endfor %}

As stated in comments, you should use the CollectionType or create and use your custom FormType in the same way of it.

This will avoid the need for manually defining extra fields in your form and BTW remove the error.

EDIT

@nakashu has reminded a workaround to be used at the moment.

Just avoid the error by adding the following in your CourseGuideRowType:

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'allow_extra_fields' => true,
    ));
}

But it doesn't make you free of side effects during the handling/binding steps.

chalasr
  • 12,037
  • 3
  • 34
  • 71