skip to Main Content

This Symfony form question has been asked 100 times (and I’ve read ALL of the responses), but none are working for me. I have a class (Employer), a form (Preview.html.twig), and a controller (DefaultController.php). No matter what I try, I still get null values for the form fields. The form displays properly and I’m not saving to a database (I just want to dump the variables, then I’ll move on to db action). This has consumed weeks of my life and any assistance is sincerely appreciated.

The Default Controller (DefaultController.php)

<?
    namespace AppController;
    
    use SymfonyBundleFrameworkBundleControllerAbstractController;
    use SymfonyComponentHttpFoundationResponse;
    use SymfonyComponentHttpFoundationRequest;
    use SymfonyComponentRoutingAnnotationRoute;
    use AppEntityEmployer;
    use AppFormEmployerType;


 class DefaultController extends AbstractController
 {  /**
    * @Route("/preview", name="preview")
    */
    public function preview(Request $request)
       {  
          $employer = new Employer();
    
          $form = $this->createForm(EmployerType::class, $employer, ['csrf_protection' => false]);
    
          $form->handleRequest($request);
    
          //the next two lines were added to force the form to submit, which it wasn't doing prior to
          if ($request->isMethod('POST')) {
            $form->submit($request->request->get($form->getName()));
            
            if ($form->isSubmitted() && $form->isValid()) {
    
                  $employer = $form->getData();
                  dump($form);     /****** ALL ENTRIES FROM THIS DUMP ARE NULL. *****/
                  exit;            /***Added to capture dump ******/
                  return $this->redirectToRoute('homepage');  /** Works when the exit is removed ***/
                }
              }

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

The Employer Class (Employer.php)

namespace AppEntity;

class Employer
{
  protected $companyName;
  protected $companyAddress;

  public function setCompanyName($companyName)
  { $this->companyName = trim($companyName); }

  public function getCompanyName()
  { return $this->companyName; }

  public function setCompanyAddress($companyAddress)
  { $this->companyAddress = trim($companyAddress); }

  public function getCompanyAddress()
  { return $this->companyAddress; }
}

Form Builder (EmployerType.php)

<?php

namespace AppForm;

use AppEntityEmployer;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolver;
use SymfonyComponentFormExtensionCoreTypeTextType;
use SymfonyComponentFormExtensionCoreTypeSubmitType;

class EmployerType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    { 
        $builder
            ->add('companyName', TextType::class, ['label' => 'Company Name', 'required' => false])
            ->add('companyAddress', TextType::class, ['label' => 'Address', 'required' => false])
            ->add('submit',SubmitType::class, ['label' => 'Submit & Preview'])
            ->getForm()   //I've added and removed this line multiple times. Not sure if its needed.
          ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Employer::class,
        ]);
    }
}

For Display (Preview.html.twig) ** Displays Form Correctly **

{{ form(form) }}

A few rabbit holes:

  1. The site is running on localhost (Symfony, Apache, MySQL).
  2. The form input is sent via POST.
  3. The Default Controller redirects after the Submit; the "exit" was added to pause my code.
  4. The form is not embedded. I’ve scaled back the entire project because I thought the embedded form was the issue.
  5. I changed the method to PUT and can see the form values appended to the URL, but $employer = $form->getData() still populates $employer with null values.
  6. I tried to get individual form fields upon submit using $form->get(‘companyName’)->getData(); The data remains null.

I’m out of ideas on how to save the form data to the Employer object.

2

Answers


  1. Chosen as BEST ANSWER

    I gave up and created a fresh instance of Symfony using Composer. Starting over led me to the issue. Something (I'm not yet confident of what) in my custom twig file was causing the problem. I'll update everyone once I figure it out.

    Final Findings: The name attribute for my form inputs were incorrect. The controller was expecting named input in the form of:

    formName[formField] //Ex: employer[companyName]
    

    and mine were the standard type generated by Twig (formName_formField)

    The addition of:

     <p>form.vars: </p>
        {{ dump(form.vars) }}
    

    in my Twig file led me to the answer. I modified the input using a custom form theme by first adding the following line to twig.yaml:

    form_themes: ['custom_bootstrap.html.twig']
    

    Then, in the custom file, I created a new instance for each type of input I use to override the defaults. For example, for checkboxes my code is:

    {% use "form_div_layout.html.twig" %}
    
    {%- block checkbox_widget -%}
        <input type="checkbox" id="{{ form.vars.name }}" name="{{ full_name }}"
          {%- if disabled %} disabled="disabled"{% endif -%}
          {%- if required %} required="required"{% endif -%}
          {% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %}
          {{ block('attributes') }}
        />
    {%- endblock checkbox_widget -%}
    

    You should be able to add the name values directly to your twig template without using a custom file. I really hope this helps someone save time.


  2. You must delete getForm() in EmployeType.
    In DefaultController, delete the line that contains form->submit(). Here the employee that you initialized is the form which fills it automatically. To retrieve your employee, you no longer need to do $form->getData(). The employee is already full. You can check with dd($employer) instead of $employer = $form->getData()

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search