symfony forms
TRANSCRIPT
Forms!1
Monday, October 14, 13
Symfony Forms
• Tipos de formularios
2
Monday, October 14, 13
Symfony Forms
• Tipos de formularios
• Formatos de datos
3
Monday, October 14, 13
Symfony Forms
• Tipos de formularios
• Formatos de datos
• Creación
4
Monday, October 14, 13
Symfony Forms
• Tipos de formularios
• Formatos de datos
• Creación
• Renderizado
5
Monday, October 14, 13
Symfony Forms
• Tipos de formularios
• Formatos de datos
• Creación
• Renderizado
• Submit
6
Monday, October 14, 13
Symfony Forms
• Tipos de formularios
• Formatos de datos
• Creación
• Renderizado
• Submit
• Eventos
7
Monday, October 14, 13
http://www.flickr.com/photos/edgarjediza/2404477249/
Objetivo
Monday, October 14, 13
Y no...
http://fun.mee.is/wp-content/uploads/funny-sleep-positon-01.jpgMonday, October 14, 13
Tipos de formularios
10
Monday, October 14, 13
Tipos de formularios
• Describen el elemento a mostrar
11
Monday, October 14, 13
Tipos de formularios
• Describen el elemento a mostrar
• Existen solamente una vez en la aplicación
12
Monday, October 14, 13
Tipos de formularios
• Describen el elemento a mostrar
• Existen solamente una vez en la aplicación
• Existe un tipo base: form
13
Monday, October 14, 13
Tipos de formularios
• Describen el elemento a mostrar
• Existen solamente una vez en la aplicación
• Existe un tipo base: form
• Se pueden heredar
14
Monday, October 14, 13
Tipos de formularios
• Describen el elemento a mostrar
• Existen solamente una vez en la aplicación
• Existe un tipo base: form
• Se pueden heredar
• Inyectar dependencias si y solo si son comunes a todas las instancias
15
Monday, October 14, 13
Tipos de formularios
• Describen el elemento a mostrar
• Existen solamente una vez en la aplicación
• Existe un tipo base: form
• Se pueden heredar
• Inyectar dependencias si y solo si son comunes a todas las instancias
• Symfony incorpora muchos campos built-in
16
Monday, October 14, 13
Tipos de formulariosCampos textoCampos texto
text textarea email
integer money number
password percent search
url
Campos choiceCampos choice
choice entity country
language locale timezone
currency
Campos date & timeCampos date & time
date datetime time
birthday
Otros camposOtros campos
checkbox file radio
hidden
Grupos de camposGrupos de campos
collection repeated
Campos buttonCampos button
button reset submit
17
Monday, October 14, 13
Tipos de formularios
<?php
namespace IsmaAmbrosi\MyBundle\Form;
use Symfony\Component\Form\AbstractType;
class MyFormType extends AbstractType{ public function getName() { return 'my_form'; }}
Tipos de formularios propios
18
Monday, October 14, 13
Tipos de formulariosTipos de formularios propios
<?php
namespace IsmaAmbrosi\MyBundle\Form;
use Symfony\Component\Form\AbstractType;use Symfony\Component\Form\FormBuilderInterface;
class MyFormType extends AbstractType{ /** * Construye el formulario */ public function buildForm(FormBuilderInterface $builder, array $options) { # Agrega un campo text para ingresar el nombre $builder->add('name', 'text'); }
public function getName(){...}}
Monday, October 14, 13
Tipos de formulariosTipos de formularios propios asociados a una entidad<?php
namespace IsmaAmbrosi\MyBundle\Form;
use Symfony\Component\Form\AbstractType;use Symfony\Component\Form\FormBuilderInterface;use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class MyFormType extends AbstractType{ public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('name'); $builder->add('last_name'); }
public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array('data_class' => 'IsmaAmbrosi\MyBundle\Entity\User')); }
public function getName(){...}}
Monday, October 14, 13
Tipos de formulariosTipos de formularios propios asociados a una entidad
<?php
namespace IsmaAmbrosi\MyBundle\Form;
use Symfony\Component\Form\AbstractType;use Symfony\Component\Form\FormBuilderInterface;use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class MyFormType extends AbstractType{ public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('name'); $builder->add('last_name'); }
public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array('data_class' => 'IsmaAmbrosi\MyBundle\Entity\User')); }
public function getName(){...}}
<?php
namespace IsmaAmbrosi\MyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/** * @ORM\Entity */class User{ /** * @ORM\Column(type="string", length=100) */ private $name;
/** * @ORM\Column(type="string", length=100) */ private $lastName;}
Monday, October 14, 13
Tipos de formulariosTipos de formularios propios
¡Se pueden crear como servicios!
Monday, October 14, 13
Tipos de formulariosTipos de formularios propios como servicios
• Puedo inyectar dependencias
Monday, October 14, 13
Tipos de formulariosTipos de formularios propios como servicios
• Puedo inyectar dependencias
• Puedo configurar un logger exclusivo
Monday, October 14, 13
Tipos de formulariosTipos de formularios propios como servicios
• Puedo inyectar dependencias
• Puedo configurar un logger exclusivo
• Puedo testear mi aplicacion sin depender de ellos
Monday, October 14, 13
Tipos de formulariosTipos de formularios propios como servicios
• Puedo inyectar dependencias
• Puedo configurar un logger exclusivo
• Puedo testear mi aplicacion sin depender de ellos
• Y más...
Monday, October 14, 13
Instancias de Formularios
• Existen una o más veces en la aplicación
• Los datos pueden cambiar luego de su creación
• Son creados a partir del tipo de formulario
27
Monday, October 14, 13
Formatos de datos
28
Monday, October 14, 13
Formatos de datos
• Formato del modelo (model format)
• Formato de la vista (view format)
• Formato normalizado (normalized format)
29
Monday, October 14, 13
Formatos de datosModel format
Formato que existe en nuestro modelo.Ej: Tal cual querémos que sea persistido por nuestro ORM
30
Monday, October 14, 13
Formatos de datosView format
Tal cual va a ser mostrado al usuario en los elementos de nuestra vista.Ej: Un objeto DateTime se transforma en un array("year" => 2013, "month" => 10, "day" => 12)
31
Monday, October 14, 13
Formatos de datosNormalized format
Formato intermedio entre la vista y el modelo.Se recomienda que este formato guarde cuanta información sea posible.
32
Monday, October 14, 13
Formatos de datosAl crear el formulario
Normalized data View dataModel data
33
Monday, October 14, 13
Formatos de datosAl crear el formulario
Normalized data View dataModel data
34
Monday, October 14, 13
Formatos de datosSubmit
Normalized data View dataModel data
35
Monday, October 14, 13
Formatos de datosSubmit
Normalized data View dataModel data $_POSTnew User
36
Monday, October 14, 13
Creación
37
Monday, October 14, 13
Creación<?php
namespace IsmaAmbrosi\MyBundle\Controller;
use IsmaAmbrosi\MyBundle\Form\MyFormType;use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller{ public function indexAction() { $form = $this->createForm(new MyFormType(), $data, $options);
# MyFormType definido como servicio $form = $this->createForm('my_form_type', $data, $options); }}
38
Monday, October 14, 13
Creaciónpublic function indexAction(){ $form = $this->createForm(new MyFormType(), $data, $options);
# MyFormType definido como servicio $form = $this->createForm('my_form_type', $data, $options);}
public function indexAction(){ $form = $this->get('form.factory')->create(new MyFormType(), $data, $options);
# MyFormType definido como servicio $form = $this->get('form.factory')->create('my_form_type', $data, $options);}
39
Monday, October 14, 13
Renderizado
40
Monday, October 14, 13
Renderizado
<?php
namespace IsmaAmbrosi\MyBundle\Controller;
use IsmaAmbrosi\MyBundle\Form\MyFormType;use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller{ public function indexAction() { $form = $this->createForm(new MyFormType(), $data, $options);
return $this->render('IsmaAmbrosiMyBundle:Default:index.html.twig', array( 'form' => $form->createView() )); }}
Creamos la vista del formulario para enviarla al template
41
Monday, October 14, 13
Renderizado
<form action="/post" method="post"> {{ form_widget(form) }}
<button type="submit">Submit</button></form>
Mostrando el formulario dentro de un tag form
42
Monday, October 14, 13
Renderizado
<form action="/post" method="post"> {{ form_row(form.name) }} {{ form_row(form.last_name) }}
{{ form_rest(form) }} <button type="submit">Submit</button></form>
Mostrando cada elemento del formulario
43
Monday, October 14, 13
Renderizado
<form action="/post" method="post"> {{ form_row(form.name) }} {{ form_row(form.last_name) }}
{{ form_rest(form) }} <button type="submit">Submit</button></form>
Mostrando cada elemento del formulario
Muestra los elementosrestantes
44
Monday, October 14, 13
Renderizado
{{ form_start(form) }} {{ form_errors(form) }}
<div> {{ form_label(form.name) }} {{ form_errors(form.name) }} {{ form_widget(form.name) }} </div>
<div> {{ form_label(form.last_name) }} {{ form_errors(form.last_name) }} {{ form_widget(form.last_name) }} </div>
<button type="submit">Submit</button>{{ form_end(form) }}
Utilizando las funciones de Symfony
45
Monday, October 14, 13
Renderizado
{{ form_start(form) }} {{ form_errors(form) }}
<div> {{ form_label(form.name) }} {{ form_errors(form.name) }} {{ form_widget(form.name) }} </div>
<div> {{ form_label(form.last_name) }} {{ form_errors(form.last_name) }} {{ form_widget(form.last_name) }} </div>
<button type="submit">Submit</button>{{ form_end(form) }}
Utilizando las funciones de Symfony
public function indexAction(){ $form = $this->createForm(new MyFormType(), $data, array( 'action' => '/post', # URL donde el formulario va a ser enviado 'method' => 'POST' # PUT, DELETE, PATCH, GET ));
return $this->render('IsmaAmbrosiMyBundle:Default:index.html.twig', array( 'form' => $form->createView() ));}
46
Monday, October 14, 13
Renderizado
<form action="/post" method="post"> <?php echo $view['form']->row($form['name']) ?> <?php echo $view['form']->row($form['last_name']) ?>
<button type="submit">Submit</button></form>
Utilizando templates php
47
Monday, October 14, 13
Submit
48
Monday, October 14, 13
Submit
Submit
49
Monday, October 14, 13
Submit
Submit Bind
50
Monday, October 14, 13
Submit
Submit Bind Validación
51
Monday, October 14, 13
Submit
Submit Bind Validación
Éxito
Error
52
Monday, October 14, 13
Submit
Submit Bind Validación
Éxito
Error
Mensaje de errorStatus 400
Persistencia del modeloMensaje de éxito
Status 2xx
53
Monday, October 14, 13
Submit
¿Código?
54
Monday, October 14, 13
Submit
public function postAction(Request $request) { $form = $this->createForm(new MyFormType(), $data, $options); $form->handleRequest($request); if (!$form->isValid()) { throw new BadRequestHttpException('Error'); }
# Persistir entidades # Mensajes # etc.
return new Response('Success'); }
55
Monday, October 14, 13
public function postAction(Request $request) { $form = $this->createForm(new MyFormType(), $data, $options); $form->handleRequest($request); if (!$form->isValid()) { throw new BadRequestHttpException('Error'); }
# Persistir entidades # Mensajes # etc.
return new Response('Success'); }
Submitsubmit
bind
validación
éxito
error
56
Monday, October 14, 13
Submit
public function postAction(Request $request){ $form = $this->createForm(new MyFormType()); $form->handleRequest($request); if (!$form->isValid()) { $this->render('IsmaAmbrosiMyBundle:Default:index.html.twig', array( 'form' => $form->createView() )); }
$manager = $this->getDoctrine()->getManager(); $manager->persist($form->getData()); $manager->flush();
return $this->redirect('/');}
57
Monday, October 14, 13
Submit
public function postAction(Request $request){ $form = $this->createForm(new MyFormType()); $form->handleRequest($request); if (!$form->isValid()) { $this->render('IsmaAmbrosiMyBundle:Default:index.html.twig', array( 'form' => $form->createView() )); }
$manager = $this->getDoctrine()->getManager(); $manager->persist($form->getData()); $manager->flush();
return $this->redirect('/');}
Internamente crea la instancia de User
Obtiene la entidad
58
Monday, October 14, 13
Eventos
59
Monday, October 14, 13
Eventos
• Permiten construir el formulario basandose en los datos
• Permiten construir el formulario basandose en el estado de la aplicación
• Permiten configurar el modelo en base a los datos recibidos
60
Monday, October 14, 13
EventosEventos lanzados por el EventDispatcher
• PRE_SET_DATA (form.pre_set_data)
• POST_SET_DATA (form.post_set_data)
• PRE_SUBMIT (form.submit)
• SUBMIT (form.bind)
• POST_SUBMIT (form.post_bind)
61
Monday, October 14, 13
Eventos
• Permite modificar los datos asignados al formulario desde nuestro modelo.
• Permite modificar el formulario en base a los datos del modelo
• Permite modificar el formulario en base al estado de mi aplicación
PRE_SET_DATA
62
Monday, October 14, 13
EventosPRE_BIND
Nos permite acceder y modificar los datos tal cual fueron enviados por el navegador en el submit.
63
Monday, October 14, 13
EventosBIND
Nos permite modificar los datos en su estado normalizado.
64
Monday, October 14, 13
EventosPOST_BIND
Nos permite acceder a los datos de la vista y modificar los datos que ya fueron asignados al modelo.
65
Monday, October 14, 13
EventosAl crear el formulario
Normalized data View dataModel data
PRE_SET_DATA POST_SET_DATA
66
Monday, October 14, 13
EventosSubmit
Normalized data View dataModel data
POST_BIND PRE_BINDBIND
67
Monday, October 14, 13
Resumen
68
Monday, October 14, 13
Resumen
1. Creamos el formulario basado en un tipo
2. Creamos la vista para ese formulario
3. Mostramos el template
Vista
69
Monday, October 14, 13
Resumen1. Creamos el formulario basado en un tipo
2. Enlazamos el $request
3. Validamos
1. Error
1. Mostramos el formulario indicando errores
2. Retornamos STATUS 400
2. Éxito
1. Persistimos entidades
2. Mensaje de éxito (Ej: Redirección a un listado)
Submit
70
Monday, October 14, 13
¿Preguntas?
71
Monday, October 14, 13
¡Gracias!
72
Monday, October 14, 13