craue / CraueFormFlowBundle

Multi-step forms for your Symfony project.
MIT License
736 stars 118 forks source link

Data from previous step not available. Form renders old data. #374

Open JoostFaber opened 3 years ago

JoostFaber commented 3 years ago

Hello,

Im using this bundle for the creation of a course, so that the create process is separated into multiple steps. For each step I’m using the same FormType which contains some CollectionTypes to create a multi level nested form. To keep things simple I will only describe the first 2 steps.

Form1 = General course information which has the course entity as data class + CollectionType for the entity ‘specialization’ Form2 = Course objectives (which contains an EntityType of the specializations rendered as checkboxes)

example_github

Although the general purpose of this bundle is to store the data in the session until all steps are completed I have changed to example code a bit to save it at each step.

`public function createCourseNew(Request $request) { $em = $this->getDoctrine()->getManager(); $formData = new Course(); $flow = $this->get("form.flow.courseflow");

    $flow->bind($formData);
    $steps = $flow->getSteps();
    $form = $flow->createForm();

    if ($flow->isValid($form)) {
        $flow->saveCurrentStepData($form);
        if ($flow->nextStep()) {
            // form for the next step
            $form = $flow->createForm();

            foreach($steps as $key => $step) {
                if($step->getNumber() == 1) {
                    $em->persist($formData);
                    $em->flush();
                }
                if($step->getNumber() == 2) {
                    $objectives = $formData->getObjectives();
                    foreach ($objectives as $objective) {
                        $em->persist($objective);
                        $em->flush();
                    }
                }
            }
        } else {
            $flow->reset(); // remove step data from the session
            return $this->redirect($this->generateUrl('view_courses')); // redirect when done
        }
    }

    return $this->render("/courses/create_new_2.html.twig", array(
        'form' => $form->createView(),
        'flow' => $flow,
        'step' => $flow->getCurrentStepNumber(),
    ));

}`

The problem i'm facing is that the specializations that I have created in step 1 aren't shown in the EntityType field in step 2 although the specializations are saved in the DB after submitting step 1. I only see specializations that where already saved in the DB earlier.

Only after manual refreshing the page at step 2 these specialization records from step 1 are shown.

form step 1 github step 1

confirmation of saved data DB records

before refresh step 2 before refresh

after refresh step 2 after refresh

So my question is when are these forms populated with the data? Because from this behavior it looks like every form gets populated from step 1 (it only loads the specializations that were submitted ealier and not the specializations that are created from step 1)

mcgoode commented 3 years ago

Have you tried to use the entity manager to get the saved data and replace the current form data with that before going to the next step? That is probably what I would try.

I gave the users the option to save the form and come back to it later in my app and I do this operation just after the valid check.

       if( $flow->isValid($form) ){

             ...... 

            // if we find that save progress is set to true we save everything and redirect to is order list.
            if( $request->get($form->getName())['saveProgress'] == true){
                $this->addFlash('success','Order successfully saved!');

                // flow finished
                $em = $this->getDoctrine()->getManager();
                $em->persist($order);
                $em->flush();
                $flow->reset(); // remove step data from the session

                return $this->redirect($this->generateUrl('orders')); // redirect when done
            }

           ......

     }