Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Nota
El componente Form de Symfony es una biblioteca independiente que
puedes utilizar fuera de los proyectos Symfony2. Para ms informacin,
consulta el Componente Form de Symfony2 en Github.
class Task
{
protected $task;
protected $dueDate;
{
return $this->task;
}
public function setTask($task)
{
$this->task = $task;
}
Nota
Si ests codificando este ejemplo, primero crea el
paquete AcmeTaskBundle ejecutando la siguiente orden (aceptando todas
las opciones predeterminadas):
$ php app/console generate:bundle --namespace=Acme/TaskBundle
Construyendo el formulario
Ahora que has creado una clase Task, el siguiente paso es crear y
reproducir el formulario HTML real. En Symfony2, esto se hace
construyendo un objeto Form y luego pintndolo en una plantilla. Por
ahora, esto se puede hacer en el interior de un controlador:
// src/Acme/TaskBundle/Controller/DefaultController.php
namespace Acme\TaskBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Acme\TaskBundle\Entity\Task;
use Symfony\Component\HttpFoundation\Request;
$form = $this->createFormBuilder($task)
->add('task', 'text')
->add('dueDate', 'date')
->getForm();
Truco
Este ejemplo muestra cmo crear el formulario directamente en el
controlador. Ms adelante, en la seccin Creando clases Form,
aprenders cmo construir tu formulario en una clase independiente, lo
cual es muy recomendable puesto que vuelve reutilizable tu formulario.
La creacin de un formulario requiere poco cdigo relativamente, porque
los objetosform de Symfony2 se construyen con un generador de
formularios. El propsito del generador de formularios es permitirte
escribir sencillas recetas de formulario, y hacer todo el trabajo pesado
de la contruccin de un formulario.
En este ejemplo, aadiste dos campos al formulario task y dueDate
que corresponden a las propiedades task y dueDate de la clase Task.
Tambin asignaste a cada uno un tipo (por ejemplo, text, date), el cual
entre otras cosas, determina qu etiqueta de formulario HTML se dibuja
para ese campo.
Symfony2 viene con muchos tipos integrados que explicaremos en breve
(consultaTipos de campo integrados).
Reproduciendo el formulario
Ahora que creaste el formulario, el siguiente paso es dibujarlo. Lo puedes
hacer pasando un objeto view especial para formularios a tu plantilla (ten
en cuenta la declaracin $form->createView() en el controlador de arriba)
y usando un conjunto de funciones ayudantes de formulario:
Twig
{# src/Acme/TaskBundle/Resources/views/Default/new.html.twig #}
<form action="{{ path('task_new') }}" method="post" {{
form_enctype(form) }}>
{{ form_widget(form) }}
</form>
PHP
</form>
Nota
Este ejemplo asume que has creado una ruta llamada task_new que
apunta al controlador AcmeTaskBundle:Default:new creado anteriormente.
Eso es todo! Al imprimir form_widget(form), se pinta cada campo en el
formulario, junto con la etiqueta y un mensaje de error (si lo hay). Tan
fcil como esto, aunque no es muy flexible (todava). Por lo general,
querrs reproducir individualmente cada campo del formulario para que
Truco
El sistema de formularios es lo suficientemente inteligente como para
acceder al valor de la propiedad protegida task a travs de los
mtodos getTask() y setTask() de la clase Task. A menos que una propiedad
sea pblica, debe tener mtodos captadores y definidores para que el
componente Form pueda obtener y fijar datos en la propiedad. Para una
propiedad booleana, puedes utilizar un mtodo isser (por es servicio,
por ejemplo, isPublished()) en lugar de un captador (por
ejemplo, getPublished() o getReminder()).
Nuevo en la versin 2.1: La compatibilidad para los mtodos hasser se
aadi enSymfony 2.1.
$form = $this->createFormBuilder($task)
->add('task', 'text')
->add('dueDate', 'date')
->getForm();
if ($request->isMethod('POST')) {
$form->bind($request);
if ($form->isValid()) {
// realiza alguna accin, tal como guardar la tarea en la base de datos
return $this->redirect($this->generateUrl('task_success'));
}
}
// ...
}
Nota
Nota
Redirigir a un usuario despus de un exitoso envo de formulario evita
que el usuario pueda hacer clic en actualizar y volver a enviar los datos.
Validando formularios
En la seccin anterior, aprendiste cmo se puede presentar un formulario
con datos vlidos o no vlidos. En Symfony2, la validacin se aplica al
objeto subyacente (por ejemplo, Task). En otras palabras, la cuestin no es
si el formulario es vlido, sino ms bien si el objeto $task es vlido
despus de aplicarle los datos enviados en el formulario. Invocar a $form>isValid() es un atajo que pregunta al objeto $task si tiene datos vlidos o
no.
La validacin se realiza aadiendo un conjunto de reglas (llamadas
restricciones) a una clase. Para ver esto en accin, aade restricciones de
validacin para que el campo task no pueda estar vaco y el
# Acme/TaskBundle/Resources/config/validation.yml
Acme\TaskBundle\Entity\Task:
properties:
task:
- NotBlank: ~
dueDate:
- NotBlank: ~
- Type: \DateTime
Annotations
// Acme/TaskBundle/Entity/Task.php
class Task
/**
* @Assert\NotBlank()
*/
public $task;
/**
* @Assert\NotBlank()
* @Assert\Type("\DateTime")
*/
protected $dueDate;
XML
<class name="Acme\TaskBundle\Entity\Task">
<property name="task">
</property>
<property name="dueDate">
<constraint name="Type">\DateTime</constraint>
</property>
</class>
PHP
// Acme/TaskBundle/Entity/Task.php
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Type;
class Task
// ...
$metadata->addPropertyConstraint('dueDate', new
Type('\DateTime'));
}
Validando grupos
Truco
Si no ests utilizando la validacin de grupos, entonces puedes saltarte
esta seccin.
Si tu objeto aprovecha la validacin de grupos, tendrs que especificar la
validacin de grupos que utiliza tu formulario:
$form = $this->createFormBuilder($users, array(
'validation_groups' => array('registration'),
))->add(...);
Si vas a crear clases form (una buena prctica), entonces tendrs que
agregar lo siguiente al mtodo getDefaultOptions():
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
},
));
}