Pedro Flores
Developer, happy husband and now a happy father!
Miryam Godoy
CODELAB
31/08/2024
https://meet.google.com/psd-mrvz-gzb
Para ver mejor las presentaciones y la pantalla de ejercicios
hay un link generado para pode acceder al google meet:
https://meet.google.com/psd-mrvz-gzb
Crear y procesar formularios HTML es una tarea difícil y repetitiva. Es necesario lidiar con la representación de campos de formulario HTML, la validación de datos enviados, la asignación de los datos del formulario a objetos y mucho más.
Es importante entender el concepto de "tipo de formulario". En otros proyectos, es habitual diferenciar entre "formularios" y "campos de formulario". En Symfony, todos ellos son "tipos de formulario":
Tipos
<input type="text">
campo de formulario es un "tipo de formulario" (por ejemplo TextType
);PostalAddressType
);<form>
de múltiples campos para editar un perfil de usuario es un "tipo de formulario" (por ejemplo UserProfileType
, ).Si su controlador se extiende desde AbstractController , utilice el createFormBuilder():
Creación de formularios en controladores
// src/Controller/TaskController.php
namespace App\Controller;
use App\Entity\Task;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class TaskController extends AbstractController
{
public function new(Request $request): Response
{
// creates a task object and initializes some data for this example
$task = new Task();
$task->setTask('Write a blog post');
$task->setDueDate(new \DateTime('tomorrow'));
$form = $this->createFormBuilder($task)
->add('task', TextType::class)
->add('dueDate', DateType::class)
->add('save', SubmitType::class, ['label' => 'Create Task'])
->getForm();
// ...
}
}
Symfony recomienda incluir la menor cantidad de lógica posible en los controladores. Por eso es mejor mover formularios complejos a clases dedicadas en lugar de definirlos en acciones de controladores. Además, los formularios definidos en clases se pueden reutilizar en múltiples acciones y servicios.
Creación de clases de formulario
Creación de clases de formulario
// src/Form/Type/TaskType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class TaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('task', TextType::class)
->add('dueDate', DateType::class)
->add('save', SubmitType::class)
;
}
}
Creación de clases de formulario
La clase de formulario contiene todas las instrucciones necesarias para crear el formulario de tareas. En los controladores que se extienden desde AbstractController , utilice el createForm() (de lo contrario, utilice el create()
// src/Controller/TaskController.php
namespace App\Controller;
use App\Form\Type\TaskType;
// ...
class TaskController extends AbstractController
{
public function new(): Response
{
// creates a task object and initializes some data for this example
$task = new Task();
$task->setTask('Write a blog post');
$task->setDueDate(new \DateTime('tomorrow'));
$form = $this->createForm(TaskType::class, $task);
// ...
}
}
Creación de clases de formulario
Por lo tanto, si bien no siempre es necesario, generalmente es una buena idea especificar explícitamente la data_class
opción agregando lo siguiente a la clase de tipo de formulario
// src/Form/Type/TaskType.php
namespace App\Form\Type;
use App\Entity\Task;
use Symfony\Component\OptionsResolver\OptionsResolver;
// ...
class TaskType extends AbstractType
{
// ...
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Task::class,
]);
}
}
Formularios de representación
// src/Form/Type/TaskType.php// src/Controller/TaskController.php
namespace App\Controller;
use App\Entity\Task;
use App\Form\Type\TaskType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class TaskController extends AbstractController
{
public function new(Request $request): Response
{
$task = new Task();
// ...
$form = $this->createForm(TaskType::class, $task);
return $this->renderForm('task/new.html.twig', [
'form' => $form,
]);
}
}
Procesamiento de formularios
Procesar un formulario significa traducir los datos enviados por el usuario a las propiedades de un objeto. Para que esto suceda, los datos enviados por el usuario deben escribirse en el objeto de formulario
Procesamiento de formularios
// src/Controller/TaskController.php
// ...
use Symfony\Component\HttpFoundation\Request;
class TaskController extends AbstractController
{
public function new(Request $request): Response
{
// just set up a fresh $task object (remove the example data)
$task = new Task();
$form = $this->createForm(TaskType::class, $task);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// $form->getData() holds the submitted values
// but, the original `$task` variable has also been updated
$task = $form->getData();
// ... perform some action, such as saving the task to the database
return $this->redirectToRoute('task_success');
}
return $this->renderForm('task/new.html.twig', [
'form' => $form,
]);
}
}
Procesamiento de formularios
Este controlador sigue un patrón común para manejar formularios y tiene tres rutas posibles:
$form->isSubmitted()
devuelve false
. Por lo tanto, el formulario se crea y se procesa;task
y dueDate
del $task
objeto. Luego, se valida este objeto (la validación se explica en la siguiente sección). Si no es válido, isValid() retorna false
y el formulario se vuelve a mostrar, pero ahora con errores de validación;true
. Ahora tiene la oportunidad de realizar algunas acciones utilizando el $task
objeto (por ejemplo, guardarlo en la base de datos) antes de redirigir al usuario a otra página (por ejemplo, una página de "gracias" o "éxito");Veamos un ejemplo
By Pedro Flores