1
votes

Based on documentation: http://symfony.com/doc/2.8/form/dynamic_form_modification.html#form-events-submitted-data

I prepared dynamic generated form. And everything works properly but only when I use form for adding new data (/new) when I use the same form for editing existing data - not working

  1. Simple form for "Appointment". It should work like that: User select client and then second "select" is filling proper data - depends on each client from first select. And this works ok but only when I try add new Appointment. When I try edit no.

class AppointmentType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('client', EntityType::class, array(
                'class'       => 'SystemAdminBundle:Client',
                'placeholder' => '',
            ));
        $formModifier = function(\Symfony\Component\Form\FormInterface $form, Client $client) 
        {
            $diseases = array();
            if($client !== null) {
                $diseases = $client->getDiseases();
            }
            $form->add('disease', EntityType::class, array(
                    'class'       => 'SystemAdminBundle:Disease',
                    'placeholder' => '',
                    'choices'     => $diseases,
                ));
        };
        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) use ($formModifier) {

                $data = $event->getData();

                $formModifier($event->getForm(), $data->getClient());

            }
        );

        $builder->get('client')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($formModifier) {

                $client = $event->getForm()->getData();

                $formModifier($event->getForm()->getParent(), $client);
            }
        );

    }


    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'System\AdminBundle\Entity\Appointment'
        ));
    }
}
  1. Appointment controller - here is function for add new appointment and edit. For "new" my code works, for "edit" no.
    public function newAction(Request $request)
    {
        $appointment = new Appointment();
        $form = $this->createForm(AppointmentType::class, $appointment);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {


            $data = $request->request->get('appointment');

            if(array_key_exists('name', $data)) {

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

                return $this->redirectToRoute('appointment_show', array('id' => $appointment->getId()));

            }

        }

        return $this->render('appointment/new.html.twig', array(
            'appointment' => $appointment,
            'form' => $form->createView(),
        ));

    }
    public function editAction(Request $request, Appointment $appointment)
    {
        $deleteForm = $this->createDeleteForm($appointment);
        $appointment = new Appointment();
        $editForm = $this->createForm('System\AdminBundle\Form\AppointmentType', $appointment);
        $editForm->handleRequest($request);

        if ($editForm->isSubmitted() && $editForm->isValid()) {

            $data = $request->request->get('appointment');

            if(array_key_exists('name', $data)) {

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

                return $this->redirectToRoute('appointment_show', array('id' => $appointment->getId()));

            }

            return $this->redirectToRoute('appointment_edit', array('id' => $appointment->getId()));
        }

        return $this->render('appointment/edit.html.twig', array(
            'appointment' => $appointment,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ));
    }

  1. View for "new" appointment

    {% block content %}

    {{ form_start(form) }}
        {{ form_widget(form) }}
        
    {{ form_end(form) }}

    
    window.onload = function() {

    var $sport = $('#appointment_client');

    $sport.change(function() {

      var $form = $(this).closest('form');

      var data = {};
      data[$sport.attr('name')] = $sport.val();
      data['appointment[_token]'] = $('#appointment__token').val();

      $.ajax({
        url : $form.attr('action'),
        type: $form.attr('method'),
        data : data,
        success: function(html) {

          $('#appointment_disease').replaceWith(

            $(html).find('#appointment_disease')
          );

        }
      });
    });

    };
    
    {% endblock %}
    
  1. View for "edit" appointment - it's almost the same as for "new" appointment

    {% block content %}
    {{ form_start(edit_form) }}
        {{ form_widget(edit_form) }}
        
    {{ form_end(edit_form) }}

    
    window.onload = function() {


    var $sport = $('#appointment_client');

    $sport.change(function() {

      var $form = $(this).closest('form');

      var data = {};
      data[$sport.attr('name')] = $sport.val();
      data['appointment[_token]'] = $('#appointment__token').val();

      $.ajax({
        url : $form.attr('action'),
        type: $form.attr('method'),
        data : data,
        success: function(html) {

        $('#appointment_disease').replaceWith(

        $(html).find('#appointment_disease')
    );   
    }
    });
    });

    };
    
    {% endblock %}

1
Your appointment_edit route takes an id in parameter, but your controller takes an Appointment object — how does this even work ?tchap
Hi, could you solve the problem?? I have the same problemEsopMx

1 Answers

0
votes

You create a new Appointment in your editAction and then persist it. You should take the one that's in your function parameters, handle the request and just flush, since your object is already persisted.

So remove these lines :

$appointment = new Appointment();
// ...
$em->persist($appointment);