Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Creare form con Symfony2

Impariamo ad utilizzare il componente Form del framework PHP Symfony2 basato sul pattern MVC per creare moduli di contatto con i quali permettere l'interazione tra le applicazioni Web, i database e gli utenti. Dalla creazione dei campi form alla loro validazione.
Impariamo ad utilizzare il componente Form del framework PHP Symfony2 basato sul pattern MVC per creare moduli di contatto con i quali permettere l'interazione tra le applicazioni Web, i database e gli utenti. Dalla creazione dei campi form alla loro validazione.
Link copiato negli appunti

Le form sono degli elementi fondamentali per l'interazione tra l'utente e un'applicazione Web, a questo proposito Symfony 2 ha un componente Form molto potente da implementare all'interno dei nostri progetti.

Symfony e le form

Le form possono essere automaticamente collegate ad una Entity (come quelle che abbiamo creato nelle precedenti lezioni) ed occuparsi, quindi, del loro popolamento all'interno del database in una maniera piuttosto semplice.

Supponiamo, quindi, di voler creare una form che si occupi di far inserire un libro ad un utente; riprendiamo il nostro BookController all'interno del metodo createAction ed andiamo a generare la form.

Nota: per semplicità omettiamo il campo autore dato che contiene una relazione verso un'altra tabella. Nel nostro esempio lo inseriremo noi manualmente nel codice; in un caso reale bisognerà chiaramente gestire anche questa situazione.

namespace Acme\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Acme\DemoBundle\Entity\Author;
use Acme\DemoBundle\Entity\Book;
use Symfony\Component\HttpFoundation\Request;
class BookController extends Controller
{
    public function createAction(Request $request)
    {
        $book = new Book();
        $form = $this->createFormBuilder($book)
                     ->add('title', 'text')
                     ->add('isbn', 'text')
                     ->add('description', 'textarea')
                     ->add('price', 'text')
                     ->add('save', 'submit', array('label' => 'Crea libro'))
                     ->getForm();
        $form->handleRequest($request);
        if ($form->isValid()) {
            //inserisco manualmente l'autore per semplificare l'esempio
            $em = $this->getDoctrine()->getManager();
            $author = $em->getRepository('AcmeDemoBundle:Author')->find(1);
            $book->addAuthor($author);
            $em->persist($book);
            $em->flush();
            return $this->redirect($this->generateUrl('_book'));
        }
        return $this->render(
            'AcmeDemoBundle:Book:create.html.twig',
            array(
                'form' => $form->createView()
            )
        );
    }
    //...

Abbiamo modificato il nostro controller in maniera da creare un oggetto Form che viene restituito dal metodo al nostro template. Andiamo però per gradi ed analizziamo il codice.

Innanzitutto istanziamo un oggetto Book e lo passiamo al FormBuilder; dopodiché andiamo ad inserire dei campi alla form specificandone il tipo.

Nel nostro caso sono tutti campi testuali tranne la descrizione che è una textarea. Ovviamente possiamo specificare campi di tipo select, checkbox, password, ecc. Per una lista dei campi supportati da Symfony, facciamo riferimento alla documentazione ufficiale.

Al termine attraverso il metodo handleRequest controlliamo che sia stato effettuato il submit della form e, successivamente, attraverso il metodo isValid verifichiamo che la form sia stata compilata correttamente. Vedremo tra poco come aggiungere controlli ai singoli campi.

Se la form è valida possiamo persistere il nuovo oggetto nel nostro database e, magari, effettuare un redirect ad un'altra pagina.

Nel caso un cui invece non è stato eseguito il submit della form, carichiamo il template create.html.twig passandogli la vista della form. All'interno del nostro file di template dobbiamo semplicemente inserire il seguente codice nel punto in cui vogliamo mostrare la form:

{{ form(form) }}

Con questo semplice codice, compilando i vari campi non ci resta che cliccare sul pulsante di submit per creare il libro ed inserirlo all'interno del database.

Per rendere un po' più pulito il nostro codice, però, possiamo effettuare un po' di refactoring e rendere più semplice e snello il controllore.

Creiamo quindi all'interno del bundle il file Form/Type/BookType.php:

namespace Acme\DemoBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class BookType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', 'text')
            ->add('isbn', 'text')
            ->add('description', 'textarea')
            ->add('price', 'text')
            ->add('save', 'submit', array('label' => 'Crea libro'));
    }
    public function getName()
    {
        return 'book';
    }
}

e modifichiamo così il controller:

public function createAction(Request $request)
    {
        $book = new Book();
        $form = $this->createForm(new BookType(), $book);
        $form->handleRequest($request);
        if ($form->isValid()) {
            //inserisco manualmente l'autore per semplificare l'esempio
            $em = $this->getDoctrine()->getManager();
            $author = $em->getRepository('AcmeDemoBundle:Author')->find(1);
            $book->addAuthor($author);
            $em->persist($book);
            $em->flush();
            return $this->redirect($this->generateUrl('_book'));
        }
        return $this->render(
            'AcmeDemoBundle:Book:create.html.twig',
            array(
                'form' => $form->createView()
            )
        );
    }

In questa maniera abbiamo il nostro controllore molto più pulito e semplice da leggere.

Validazione field della form

Finora abbiamo dato per scontato che i campi immessi siano validi in ogni forma ma quasi mai è così. Una componente fondamentale e spesso complessa della gestione delle form è la loro validazione. Anche in questo caso Symfony ci viene incontro attraverso gli strumenti di Validation.

Nel nostro esempio potremmo avere la necessità di verificare, oltre al fatto che tutti i campi non siano vuoti, che il titolo sia più lungo di tre caratteri, il prezzo sia un valore numerico e che l'isbn sia valido. Vediamo il codice necessario:

namespace Acme\DemoBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\GreaterThan;
use Symfony\Component\Validator\Constraints\Isbn;
class BookType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', 'text', array(
                'constraints' => array(
                new NotBlank(),
                new Length(array('min' => 3)),
            )))
            ->add('isbn', 'text', array(
                'constraints' => array(
                    new NotBlank(),
                    new Isbn()
                )))
            ->add('description', 'textarea', array(
                'constraints' => array(
                    new NotBlank(),
                )))
            ->add('price', 'text', array(
                'constraints' => array(
                    new GreaterThan(0),
                )))
            ->add('save', 'submit', array('label' => 'Crea libro'));
    }
    public function getName()
    {
        return 'book';
    }
}

Come possiamo notare, abbiamo inserito come terzo parametro per ogni field un array con una chiave constraints. All'interno della chiave abbiamo inserito quelli che sono i controlli per validare il singolo field. Nel caso in cui il campo non soddisfi tutti i requisiti, verrà visualizzato l'errore corrispondente nel campo.

Le constraints di validazione possono anche essere inserite all'interno di un file validation.yml in maniera da avere un codice più leggibile e, soprattutto, un progetto più mantenibile. Il file sarà contenuto all'interno della directory Resources/config/ del nostro bundle.

Abbiamo visto in questa lezione come gestire le form utilizzando Symfony. Nella prossima ci occuperemo di due componenti molto importanti di Symfony: il Service Container e il Dependency Injection.

Ti consigliamo anche