[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:
- src/My/HelloWorldBundle/Form
- src/My/HelloWorldBundle/Form/Type (all form classes are here)
- 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
{% endblock %}