CraueFormFlowBundle: Dynamically Changing Form Type Based on User Selection in FormFlow in a step

63 views Asked by At

I'm working on a Symfony application and I'm using the CraueFormFlowBundle for implementing a multi-step form using the FormFlow feature. I have a requirement where I need to dynamically change the form type displayed in the second step based on the user's selection in the first step.

I have two form types: AnnonceType2 and AnnonceMotoType. In the second step of my form flow, I want to display either AnnonceType2 or AnnonceMotoType depending on the selected category in the first step (AnnonceType1).

I have tried implementing the solution, but I'm facing difficulties in getting the selected category from the first step and using it to determine the form type for the second step.

Here's the relevant code snippet from my CreateAnnonceFlow class:

<?php

namespace App\Form;

use Craue\FormFlowBundle\Form\FormFlow;
use Craue\FormFlowBundle\Form\FormFlowInterface;
use App\Form\AnnonceType1;
use App\Form\AnnonceType2;
use App\Form\AnnonceMotoType;
use App\Form\AnnonceType3;
use App\Form\AnnonceType4;
use App\Form\AnnonceType5;
use App\Form\AnnonceType6;

class CreateAnnonceFlow extends FormFlow
{

    
    protected function loadStepsConfig()
    {
        
        return [
            [
                'form_type' => AnnonceType1::class,
                
            ],
            [
                'form_type' => CustomFormType::class,
                'skip' => function ($estimatedCurrentStepNumber, FormFlowInterface $flow) {
                    
                    return $estimatedCurrentStepNumber > 2 && !$flow->getFormData();
                },

            ],
            [
                'form_type' => AnnonceType3::class,
                'skip' => function ($estimatedCurrentStepNumber, FormFlowInterface $flow) {
                    return $estimatedCurrentStepNumber > 3 && !$flow->getFormData();
                },
            ],
            [
                'form_type' => AnnonceType4::class,
                'skip' => function ($estimatedCurrentStepNumber, FormFlowInterface $flow) {
                    return $estimatedCurrentStepNumber > 4 && !$flow->getFormData();
                },
            ],
            [
                'form_type' => AnnonceType5::class,
                'skip' => function ($estimatedCurrentStepNumber, FormFlowInterface $flow) {
                    return $estimatedCurrentStepNumber > 5 && !$flow->getFormData();
                },
            ],
            [
                'form_type' => AnnonceType6::class,
            ],
        ];
    }

    
}

here my CustomFormType class:

<?php

namespace App\Form;

use Symfony\Component\Form\AbstractType;
use App\Entity\Annonce;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormFactoryInterface;

class CustomFormType extends AbstractType
{
    private $formFactory;

    public function __construct(FormFactoryInterface $formFactory)
    {
        $this->formFactory = $formFactory;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // Add an event listener to handle the form submission and determine the next form type
        $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) {
            $form = $event->getForm();
            $data = $form->getData();
            $category = $data->getCategory();
            //dd($category);
            if ($category === 'auto') {
                $formType = AnnonceType2::class;
            } elseif ($category === 'moto') {
            
                $formType = AnnonceMotoType::class;
                //dd($formType);
            } 
            
            $formTypeInstance = $this->formFactory->create($formType);
        $event->getForm()->getParent()->add($formTypeInstance);
        });
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Annonce::class, // Replace with your form data class
        ]);
    }
}

0

There are 0 answers