Sam
Sam

Reputation: 14586

symfony2: form does not submit all values properly

When submitting the form below, the field 'Body' which is a textarea, is not mapped to the $message object when $form->getData(); is called.

I can see in $request.parameters that there are two values:

-form, which is an array containing the values of the form, but the textarea value is missing.

-Body, which is a string containing the value of the textarea.

Why is Body not part of the form object ?

  1. controller action :

    class ContactController extends Controller {
    
    public function indexAction(Request $request) {
      $message = new Message();
    
      $form = $this->createFormBuilder($message)
            ->add('Name', 'text', array('required' => true))
            ->add('Email', 'email')
            ->add('Subject', 'text')
            ->add('Body', 'textarea')
            ->getForm();
    
      $form->handleRequest($request);
    
       if ($form->isValid()) {
        // data is an array with "name", "email", and "message" keys
        $data = $form->getData();
       }
    
       return $this->render('PhotographPhotoBundle:Contact:index.html.twig', array('form' => $form->createView()));
     }
    }
    
  2. Message class:

    class Message
    {
       protected $name;
       protected $subject;
       protected $body;
       protected $email;
       + setters and getters here
    }
    
  3. form template

     {# src/Photograph/PhotoBundle/Resources/views/Form/fields.html.twig #}
    
      {% block field_row %}
       {% spaceless %}
        {{ form_errors(form) }}
        {{ form_widget(form) }}
       {% endspaceless %}
      {% endblock field_row %}
    
     {% block email_widget %}
        <input type="email" {{ block('widget_attributes') }} value="{{ value }}" class="field-email   form_field">       
     {% endblock %}
    
      {% block text_widget %}
        <input type="text" {{ block('widget_attributes') }} value="{{ value }}" class="field-name form_field">
      {% endblock %}
    
      {% block textarea_widget %}
        <textarea name="field-message" {{ block('widget_attributes') }}  cols="45" rows="5"  class="field-message form_field">{{ value }}</textarea>
      {% endblock %}
    
  4. the form view

         <form action="{{ path('PhotographPhotoBundle_contact') }}" method="post" class="feedback_form" >
    
                                    {{ form_errors(form) }}                                       
    
                                    {{ form_widget(form.Name) }}
                                            <div class="clear"></div>
                                    {{ form_widget(form.Email, { 'attr': {'placeholder': 'email' }}) }}
                                            <div class="clear"></div>
                                    {{ form_widget(form.Subject, { 'attr': {'placeholder': 'sujet' }}) }}
                                            <div class="clear"></div>
                                    {{ form_widget(form.Body, { 'attr': {'placeholder': 'message' }}) }}
                                            <div class="clear"></div>    
                                    <input value="envoyer votre message" type="submit"  class="feedback_go" />
                                            <div class="ajaxanswer"></div>
                                       {{ form_end(form) }}
    

Upvotes: 0

Views: 1830

Answers (2)

Cerad
Cerad

Reputation: 48865

This:

{% block textarea_widget %}
    <textarea name="field-message" {{ block('widget_attributes') }}  cols="45" rows="5"  class="field-message form_field">{{ value }}</textarea>
{% endblock %}

Should be:

{% block textarea_widget %}
    <textarea {{ block('widget_attributes') }}  cols="45" rows="5"  class="field-message form_field">{{ value }}</textarea>
{% endblock %}

In other words, drop the name attribute. First time I ever successfully debugged one of these templates!

Upvotes: 1

ferdynator
ferdynator

Reputation: 6410

The first parameter of the FormBuilder::add() method is the name of that field. It is supposed to match the property of your class. I'm not quite sure why it is only not working for the Body part. Change the form type to this:

  $form = $this->createFormBuilder($message)
    ->add('name', 'text', array('required' => true))
    ->add('email', 'email')
    ->add('subject', 'text')
    ->add('body', 'textarea')
    ->getForm();

Note the lower-case letters so they match your entity. If you want to change the label of a field you can either set it in the config array:

    ->add('body', 'textarea', array(
         'attributes' => array(
              'label' => 'Body'
         )
      )
    )

Or just change your template correctly:

<label>Body</label>
{{ form_widget(form.Body, { 'attr': {'placeholder': 'message' }}) }}

See the docs for a more clear explanation.

Upvotes: 1

Related Questions