DevWL
DevWL

Reputation: 18840

How to access submitted data inside FormType class?

How to access submitted data inside FormType class in Symfony 4/5?

Assuming that form is not mapped with any Entity and its submit back to same controller / action.

// src\Form\SomeFormType.php -----------------------------------------------------

...

public function buildForm(FormBuilderInterface $builder, array $options)
{
    /**
     * How to get submited data with in FormType class
     */
    $userChoiceSubmitedData = // ... <<<<<<<<<<<<<<<<<<
    
    /** 
     * I want to get those value on form submit 
     * (form submites to self and is not redirecting) 
    */
    $builder    
        ->add('userChoice', ChoiceType::class, [
            'placeholder' => 'Select value',
            'choices'=> [
                'ONE' => 1,
                'TWO' => 2,
            ],
        ])
        ->add('send', SubmitType::class);
    ;

    /** On form submit one of those fields should be added to the form */
    if ($getUserChoiceSubmitedData === 1) {
        /* add another field*/
        $builder
            ->add('userSelectedNum1', IntegerType::class)
        ;
    }    
    if ($getUserChoiceSubmitedData === 2) {
        /* add another field*/
        $builder
            ->add('userSelectedNum2', IntegerType::class)
        ;
    }  
    
}

...

And in controller it would look something like that:

// src\Controller\SomeController.php ---------------------------------------
... 

/**
 * @Route("/", name="index")
 */
public function index(MailerInterface $mailer, Request $request)
{
    $form = $this->createForm(CCPayFormType::class);
    $form->handleRequest($request);
    ...

    if($form->isSubmitted() && $form->isValid()){
        $userChoice = $form->getData();
        $userChoice = $form->get('userChoice')->getData(); // shows 1 or 2

        if(isset($cardType)){
            // $form->passToFormType(['userChoiceSubmitedData'=>$userChoice]) // fake code!
        }

        ...

    ...

    return $this->render('index/index.html.twig', [
        'form' => $form->createView()
    ]);
}

Upvotes: 1

Views: 1414

Answers (2)

Philipp M&#228;hler
Philipp M&#228;hler

Reputation: 116

Pass your userChoice to the form by passing custom data using the formTypes optionsResolver. It will look like this:

Controller

$payform = null; //try to pass null, but better pass an object
$userChoice =  $form->get('userChoice')->getData();
//re-create form here
$form = $this->createForm(CCPayFormType::class, $payform, array(
     'user_choice' => $userChoice,
    ));

//and render form as you did in controller 
//check the data of $form-getData() to determine, that no cardNumber is typed in

Because of the fact, that the option array is behind the object mapped to the form, you could try to pass $payform as null.

In your formType you can now do:


  /**
     * How to get submited data with in FormType class
     */
    $userChoiceSubmitedData = $options['user_choice'];

Because of the re-creation of your form you will have to initially pick your userChoice.


$builder    
        ->add('userChoice', ChoiceType::class, [
            'placeholder' => 'Select card',
            'choices'=> [
                'ONE' => 1,
                'TWO' => 2,
            ],
            'data' => $userChoiceSubmitedData,
            ])

References:

Passing data to buildForm() in Symfony 2.8, 3.0 and above

https://symfony.com/doc/current/form/without_class.html

Symfony2 Setting a default choice field selection

Hope it helps!

Upvotes: 0

Mike Doe
Mike Doe

Reputation: 17566

You can't. The builder method is executed before the request is processed. Instead you need to add an event listener:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'onSubmit']);

    …
}

…

public function onSubmit(FormEvent $event)
{
    $form = $event->getForm();
    $data = $event->getData();

    // go bananas here
}

There are many form events. You can read about them in the docs and in the FormEvents class too.

Quoting the doc block of the FormEvents::PRE_SUBMIT constant:

/**
 * The PRE_SUBMIT event is dispatched at the beginning 
   of the Form::submit() method.
 *
 * It can be used to:
 *  - Change data from the request, before submitting the data to the form.
 *  - Add or remove form fields, before submitting the data to the form.
 *
 * @Event("Symfony\Component\Form\Event\PreSubmitEvent")
 */
const PRE_SUBMIT = 'form.pre_submit';

Upvotes: 1

Related Questions