Part # 7 Forms and Validation

Forms and Validations with Symfony

[Back to Learn Symfony]

Creating forms with Symfony is quite easy, the component Form takes care of it. This component can be used with non Symfont projects.
Forms qre linked to Entities or to a class related to a Fomr, for example a ForgotPassword class.
We could generate a Form stright away in an action and then send it to a template, but to keep with good practises it is better to create the Form classes

For a Car form let's create three folders:

  1. src/My/HelloWorldBundle/Form
  2. src/My/HelloWorldBundle/Form/Type (all form classes are here)
  3. src/My/HelloWordlBundle/Form/Data  (all Data classes that are not Entities)

 

Step 1: Create the form for the class Car: Form/Type/CarType.php

Code:


namespace My\HelloBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;


class CarType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{

$builder->add('model');
$builder->add('color');
$builder->add('year');
// Bind data from table CarEnergy
$builder->add('energy', 'entity', array('class' => 'MyHelloBundle:CarEnergy','property' => 'description','multiple'=>false));
}

public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'My\HelloBundle\Entity\Car',
);
}

public function getName()
{
return 'Car';
}
}

Field Types Within Forms With Symfony 2

Email type

$builder->add('mail','email');

Will add an input type email (html5) and the html output will be:

Entity type

A widget to add two related entities data for example the main cities from one country. See the energy entity sample in the form class CarType

Please, check the full list type here: http://symfony.com/doc/current/reference/forms/types.html

 

Step 2: Update Controller

Add this at the top of the DefaultController.php file

use My\HelloBundle\Form\Type\CarType;
use My\HelloBundle\Entity\Car;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

 

Step 3: Create the action in the controller

   /**
    * @Route("/add", name="car_add")
    * @Template()
    */
    public function addAction()
    {
        $request = $this->get('request'); // Get request object through service container
        $car = new Car(); // Create a Car object
        $form=$this->createForm(new CarType(), $car);            
        if ('POST' == $request->getMethod())
        {
            $form->bindRequest($request); // Bind data to form  
            // Validation
            if ($form->isValid())
            {
                $this->get('vm.car_manager')->saveCar($car); // Use manager to save object
                // Send a message to user
                $this->get('session')->setFlash('notice',$this->get('translator')->trans('Car added'));
            // Redirect to update page
            return new RedirectResponse($this->generateUrl('car_edit', array(
            'carId' => $car->getId()
            )));
            }
        }
        return array('form' => $form->createView(), 'car' => $car); // Pass the Form object and the Car Object to the template Twig
    }

 

Step 4 : Create action edit

    /**
     * @Route("/edit/{carId}", name="car_edit")
     */
    public function editAction($carId)
    {
        $request = $this->get('request');
        // Verify Car id
        if (!$car = $this->get('my.car_manager')->loadCar($carId))
        {
            throw new NotFoundHttpException($this->get('translator')->trans('This car does not exist.'));
        }

        // Bind the car from the data base: carId
        $form = $this->get('form.factory')->create(new CarType(), $car);
        // If submit
        if ('POST' == $request->getMethod())
        {
            $form->bindRequest($request);

            if ($form->isValid())
            {
           $this->get('my.car_manager')->saveCar($car);
                $this->get('session')->setFlash('notice',$this->get('translator')->trans('Car updated.'));

                return new RedirectResponse($this->generateUrl('car_edit', array('carId' => $car->getId())));
            }
        }

        // Render form template   
        return $this->render('MyHelloBundle:Default:add.html.twig',array('form' => $form->createView(), 'car' => $car));
    }

 

Step 5: Create the View Twig template

The template's name must be the same as the action "add":

// /src/My/HelloBundle/Resources/views/Default/add.html.twig

{% extends '::base.html.twig' %}
{% block title %}{% if car.id %}{{ 'Edit car'|trans }}{% else %}{{ 'Add car'|trans }}{% endif %}{% endblock %}
{% block body %}
Welcome to my first FORM with Symfony 2

 


{% if car.id %}{{ 'Edit car'|trans }}{% else %}{{ 'Add car'|trans }}{% endif %}




{{ form_errors(form.model) }}
{{ form_label(form.model, 'Model'|trans) }}
{{ form_widget(form.model) }}



{{ form_errors(form.color) }}
{{ form_label(form.color, 'Color'|trans) }}
{{ form_widget(form.color) }}



{{ form_errors(form.year) }}
{{ form_label(form.year, 'Year'|trans) }}
{{ form_widget(form.year) }}



{{ form_rest(form) }}


{% endblock %}


[Back to Learn Symfony]