Bernhard Schussek gave a presentation on leveraging Symfony2 forms at the Symfony Live conference in March 2011. He discussed the evolution of the Symfony form component, its service-oriented architecture, and how forms are decoupled from business logic. He provided an example of an online sausage shop order form to demonstrate how form data is bound to objects and submitted. The presentation covered the form configuration class, form processing, field types, validation, embedding forms, and form themes.
16. Service implementation
class Order
{
function setName($name);
function setAddress($address);
function setSausage($sausage);
function setAmount($amount);
}
19. Flow of information
Order form
Name: Max
Address: Sensio Labs,
Paris
Sausage: Bratwurst
Amount: 5
20. Flow of information
Order form
$order
Name: Max ->setName('Max')
Address: Sensio Labs, ->setAddress(
'Sensio Labs,
Paris
Paris')
Sausage: Bratwurst ->setSausage(
'Bratwurst')
Amount: 5 ->setAmount(5);
21. Flow of information
Existing order
$order
->getName() Name: Bob
->getAddress() Address: Liip Office
Zurich
->getSausage() Sausage: Cervelat
->getAmount(); Amount: 10
30. Form processing Form identifier
$factory = $this->get('form.factory');
$form = $factory->getInstance('form.order');
$form->setData($order);
if ($request->getMethod() === 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
$order->send();
return new RedirectResponse(...);
}
}
31. Form processing
$factory = $this->get('form.factory');
$form = $factory->getInstance('form.order');
$form->setData($order); Service object
if ($request->getMethod() === 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
$order->send();
return new RedirectResponse(...);
}
}
32. Form processing
$factory = $this->get('form.factory');
$form = $factory->getInstance('form.order');
$form->setData($order);
if ($request->getMethod() === 'POST') {
$form->bindRequest($request);
if ($form->isValid()) { Calls setters
$order->send();
return new RedirectResponse(...);
}
}
33. Form processing
$factory = $this->get('form.factory');
$form = $factory->getInstance('form.order');
$form->setData($order);
if ($request->getMethod() === 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
$order->send();
return new RedirectResponse(...);
}
} $order now contains submitted data!
34. Form rendering
In the action
return $this->render(
'HelloBundle:Hello:index.twig.html',
array('form' => $form->getRenderer()));
Contains view variables and methods
35. Form rendering
In the template
<form action="#" method="post">
{{ form.widget }}
</form>
"widget" is a view method
36. Form rendering
"fields" is a view variable
<form action="#" method="post">
{{ form.errors }}
{% for field in form.vars.fields %}
{{ field.errors }}
{{ field.label }}
{{ field.widget }}
{% endfor %}
{{ form.rest }}
</form>
49. Core fields
entity
birthday password
file
checkbox percent
hidden
choice repeated
integer
collection textarea
language
country text
locale
date timezone
money
datetime url
number
61. Field creation
Manual
Automatic
Symfony2 looks at metadata of the domain class to
"guess" the correct field type and settings
E.g. Validator metadata, Doctrine2 metadata
62. Manual field creation
public function configure(
FieldInterface $form, array $options)
{
$form->add('entity', 'sausage', array(
'class' => 'Sausage',
));
}
but Doctrine already knows, that "sausage" is a
ToOne relationship to the Sausage class!
63. Automatic field creation
public function configure(
FieldInterface $form, array $options)
{
$form->setDataClass('Order');
$form->add('sausage');
}
64. Automatic with options overriding
public function configure(
FieldInterface $form, array $options)
{
$form->setDataClass('Order')
->add('sausage', array(
'required' => false,
));
}
66. Embedded toone forms
public function configure(
FieldInterface $form, array $options)
{
$form->add('form.sausage', 'sausage');
}
Identifier of SausageFormConfig
67. Embedded tomany forms
public function configure(
FieldInterface $form, array $options)
{
$form->add('collection', 'sausages', array(
'identifier' => 'form.sausage'
));
}
Identifier of SausageFormConfig
72. Form themes
Core themes:
TwigBundle::div_layout.html.twig
TwigBundle::table_layout.html.twig
Configuration in the DI parameter
"form.theme.template"
More flexible configuration options coming soon
73. Questions?
Thanks for listening!
Code can currently be found on
https://github.com/bschussek/symfony/tree/experimental
Bernhard Schussek
Twitter: @webmozart