craue / CraueFormFlowBundle

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

Error : The step "3" does not exist. #303

Closed eved42 closed 6 years ago

eved42 commented 6 years ago

Hi,

I have a 2 steps form. When I click on the Reset button, I have this error : The step "3" does not exist. OutOfBoundsException

I configured 2 steps in my FormFlow class.

Is the step 3 required ?

Dranac commented 6 years ago

there could be something wrong in your step configuration, what does it looks like ?

eved42 commented 6 years ago

I think I have a problem with my second step.

I have a form to add a new prescriber in my database. The first step consists in informing the various informations about the prescriber. Then, I check if this prescriber already exists (with constraint validations of entity) or if there are similar ones (with a query).

If there are duplicates, I add a new step : I ask the user if he/she really wants to add this new prescriber.

In short, I have a 1-step form or a 2-steps form, depending on doubloons. To determine this, I used the skip parameter in my FormFlow class, in the 2nd step config.

protected function loadStepsConfig()
{
    $em = $this->em;

    return array(
        array(
            'label' => 'Add prescriber',
            'form_type' => 'AppBundle\Form\AddPrescriberType',
            'form_options' => array(
                'validation_groups' => array('Default')
            )
        ),
        array(
            'label' => 'Confirmation',
            'form_type' => 'AppBundle\Form\AddPrescriberType',
            'form_options' => array(
                'entity_manager' => $this->em
            ),
            'skip' => function($estimatedCurrentStepNumber, FormFlowInterface $flow) use (&$em) {
                if (!empty($flow->getFormData()->getId())) {
                    $rp = $em->getRepository('AppBundle:Prescriber');

                    # search if a prescriber already exists
                    $qb = $rp->createQueryBuilder('p');
                    $qb->where($qb->expr()->eq('p.rpps', ':rpps'))
                        ->orWhere($qb->expr()->like('p.lastname', ':name'))
                        ->setParameter('rpps', $flow->getFormData()->getRpps())
                        ->setParameter('name', '%'.$flow->getFormData()->getLastname().'%');

                    $results = $qb->getQuery()->getArrayResult();

                    # skip this step if no duplicate items
                    return ($estimatedCurrentStepNumber > 1 && empty($results)) ? true : false;

                } else {
                    return false;
                }
            }
        )
    );
}

It appears it isn't the good way to do this because $flow->getFormData() doesn't exists yet when skip function is executed...

Should I do this in my controller action ? How ?

Dranac commented 6 years ago

I don't think you can skip the last step of your form. In the docs you can see that there is this example :

protected function loadStepsConfig() {
    return array(
        array(
            'form_type' => 'MyCompany\MyBundle\Form\CreateVehicleStep1Form',
        ),
        array(
            'form_type' => 'MyCompany\MyBundle\Form\CreateVehicleStep2Form',
            'skip' => true,
        ),
        array(
        ),
    );
}

Maybe add an empty array as a 3rd step.

craue commented 6 years ago

It's fine to call $flow->getFormData() and also to skip the last step, so I don't see why you're getting this error. Can you give more details, maybe a stack trace or even simplified failing code? When exactly does it happen? Only when clicking reset? In which step(s)?

eved42 commented 6 years ago

Sorry, since this I found another way to do what I wanted (with forward method in my controller, I don't use your bundle anymore).

I remember the error occured when I clicked on the Reset button at the second step, no error for the first. I don't remember very well but I remember I wrote something like this :

protected function loadStepsConfig()
{
    $em = $this->em;

    return array(
        array(
            'label' => 'Add prescriber',
            'form_type' => 'AppBundle\Form\AddPrescriberType',
            'form_options' => array(
                'validation_groups' => array('Default')
            )
        ),
        array(
            'label' => 'Confirmation',
            'skip' => function($estimatedCurrentStepNumber, FormFlowInterface $flow) use (&$em) {
                $rp = $em->getRepository('AppBundle:Prescriber');

                # search if a prescriber already exists
                $qb = $rp->createQueryBuilder('p');
                $qb->where($qb->expr()->eq('p.rpps', ':rpps'))
                    ->setParameter('rpps', $flow->getFormData()->getRpps());

                $results = $qb->getQuery()->getArrayResult();

                # skip this step if no duplicate items
                return ($estimatedCurrentStepNumber > 1 && empty($results)) ? true : false; 
            }
        )
    );
}

At the beginning, I didn't configure a form_type parameter to last step (like in the example of the documentation). Sorry, if I have a time, I will test it again to give your more details.

craue commented 6 years ago

Thanks for reporting. I was eventually able to reproduce the issue. It's fixed now in 2.1.10 and 3.0.3.