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
- 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' )); } }
- 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(), )); }
- 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 %}
- 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 %}
appointment_edit
route takes an id in parameter, but your controller takes anAppointment
object — how does this even work ? – tchap