2

I'm following the tutorial at http://symfony.com/doc/current/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms

However every attempt gives me this error. Note: Real bundle renamed for AcmeBundle.

Catchable Fatal Error: Argument 1 passed to
AcmeBundle\Form\ScheduleType::AcmeBundle\Form\{closure}()
must be an instance of
AcmeBundle\Form\FormInterface,
instance of Symfony\Component\Form\Form given,
called in
/var/www/acme/api/src/AcmeBundle/Form/ScheduleType.php on line 52 and defined 

/var/www/acme/api/src/AcmeBundle/Form/ScheduleType.php

<?php

namespace AcmeBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;

// form input types
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TimeType;

//use AcmeBundle\Entity\Classes;
//use AcmeBundle\Entity\Subject;

class ScheduleType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder->add('Classes',
                          EntityType::class,
                          array('class'         => 'AcmeBundle:Classes',
                                'expanded'      =>  false,
                                'placeholder' => '',
                                'multiple'      =>  false,
                                'label'         =>  'Class'));
 35
        $formModifier = function (FormInterface $form, Classes $classes = null) {
            $subjects = null === $classes ? array() : $classes->getSubjects();

            $form->add('position', EntityType::class, array(
                'class'       => 'AppBundle:Subject',
                'placeholder' => '',
                'choices'     => $subjects,
            ));
        };

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) use ($formModifier) {
                // this would be your entity, i.e. SportMeetup
                $data = $event->getData();

                $formModifier($event->getForm(), $data->getClasses());
            }
        );

        $builder->get('Classes')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($formModifier) {
                $classes = $event->getForm()->getData();
                $formModifier($event->getForm()->getParent(), $classes);
            }
        );
    }
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AcmeBundle\Entity\Schedule',
        ));
    }

}

src/AcmeBundle/Controller/DefaultController.php

public function addScheduleAction( Request $request )
{
    $sche = new Schedule();

    $form = $this->createForm(ScheduleType::class, $sche);
    $form->handleRequest($request);

    if( $form->isSubmitted() && $form->isValid() )
    {
        // form saving
    }

    return $this->render(   'AcmeBundle:schedule:layout_schedule_form.html.twig',
                            array(  'title'     => $translator->trans('%AddNewSchedule%'),
                                    'form'      =>  $form->createView(),
                                    'message'   => '')
    );
}

src/AcmeBundle/Resources/views/schedule/layout_schedule_form.html.twig

{% extends "AcmeBundle::layout.html.twig" %}

{% block cmi_body %}

    <div class="row">
        <div class="col-md-12">
            <p>{{ message }}</p>
        </div>
    </div>
    <div class="row">
        <div class="col-md-2">

        </div>
        <div class="col-md-6">
            {{form_start(form)}}
            {{ form_row(form.Classes) }}    {# <select id="schedule_classes" ... #}
            {{ form_row(form.Subjects) }} {# <select id="schedule_subjects" ... #}
            {{form_end(form)}}
        </div>
    </div>
<script>
var $classes = $('#schedule_classes');
$classes.change(function() {
  var $form = $(this).closest('form');
  var data = {};
  data[$classes.attr('name')] = $classes.val();
  $.ajax({
    url : $form.attr('action'),
    type: $form.attr('method'),
    data : data,
    success: function(html) {
      $('#schedule_subjects').replaceWith(
        $(html).find('#schedule_subjects')
      );
 }
  });
});
</script>
{% endblock %}

1 Answer 1

4

Seems like you just forgot to use Symfony\Component\Form\FormInterface;

Therefore it's assumed you're trying to use FormInterface from local namespace (which is AcmeBundle\Form)

Sign up to request clarification or add additional context in comments.

3 Comments

Yes that was the issue. Thanks. Now everything is set. However the ajax response comes with The CSRF token is invalid. Please try to resubmit the form. Have any idea?
I guess you're just trying re-submit data by reloading page.
CSRF token is invalid error fixed by loading the form in template in rest manner {{form_widget(form)}} with ` {{ form_rest(form) }}`

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.