Symfony formulieren

Hier volgt een handleiding hoe je een formulier kunt maken. Er wordt begonnen zonder een object (Entity) waarop het formulier gebaseerd is. Meestal zal er al echter een Entity zijn waarvan je een formulier wilt maken.

Maak een formuliercontroller

bin/console make:controller FormulierController
Symfony geeft nu aan:
created: src/Controller/FormulierController.php
created: templates/formulier/index.html.twig

Maak een formulierklasse

bin/console make:form

Er wordt gevraagd om de naam van de Class. Gebruik hiervoor de naam met type erachter. We geven hier dus de naam FormulierType. Er wordt nog gevraagd of het formulier gekoppeld is aan een Entity, je kan hier op Enter drukken aangezien dit (nog) niet het geval is. Mocht je een Entity gemaakt hebben vul hier dan de naam in. Symfony antwoordt nu met:

created: src/Form/FormulierType.php

Voeg velden toe

Open nu src/Form/FormulierType.php en laten we wat invulvelden toevoegen

<?php
namespace App\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

//Voor elk invulveld moet er een regel worden toegevoegd, in dit geval Email en Naam
+ use Symfony\Component\Form\Extension\Core\Type\EmailType;
+ use Symfony\Component\Form\Extension\Core\Type\TextType;

class FormulierType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        //Voeg hier velden toe aan het formulier"
        $builder
             //Deze is standaard en mag weg
        -            ->add('field_name')
             //En laten we deze eens toevoegen
        +            ->add('Naam', TextType::class)
        +            ->add('Email', EmailType::class)
        ;
    }
}

Wijzig de controller

Wijzig nu de controller in src/Controller/FormulierController.php.

class FormulierController extends AbstractController
{
    /**
     * @Route("/formulier", name="formulier")
     */
    public function index()
    {
        $form = $this->createForm(FormulierType::class);
        return $this->render('formulier/index.html.twig', [
        'our_form' => $form->createView(),
        ]);
    }
}

Maak een link om naar het formulier te gaan in het Twig bestand van de aanroepende pagina

<a href="{{path('formulier') }}">Formulier</a>

Pas het Formulier-Twig Template aan

Pas het Twig template aan in templates/formulier/index.html.twig

{% extends 'base.html.twig' %}

{% block title %}Contact Form{% endblock title %}

{% block body %}

    <div>
        {{# Start formulier#}}
        {{ form_start(our_form) }}

        {{# Hele formulier wordt op het scherm getoverd, je kan met Twig overigens met
        'form_' je formulier verder manipuleren, check daarvoor even de Twig documentatie.#}}
        {{ form_widget(our_form) }}

        {{# Plaats hier in HTML een submit button, kan ook anders eventueel maar nu even zo#}}
        <input type="submit" />

        {{# Einde formulier #}}
        {{ form_end(our_form) }}

         {{# Voeg dit eens toe, zo kan je zien wat Symfony allemaal meegeeft #}}
        {{ dump() }}
    </div>

{% endblock %}

Maak een object!

We hebben nu een (lelijk) formulier en een submit button, maar er moet natuurlijk ook iets gebeuren als je de gegevens van het formulier wilt controleren en opslaan. Je doet dit in de controller src/Controller/FormulierController.php. Deze moet grondig vertimmerd worden, maar laten we eerst maar eens een object gaan maken als je die nog niet hebt.

php bin/console make:entity

Noem de Entity Persoon en maak twee velden aan: Naam en Email, allebij string. De velden van het object moeten overeenkomen met de velden in het formulier. Als je klaar bent kan je je Entity bekijken in src/Entity/Persoon.php

Het zal vaker voorkomen dat je de Entity al hebt voordat je het formulier gaat maken. Je kan dan simpelweg in het begin wanneer je het formulier maakt (bovenaan deze pagina) aangeven om welke Entity het gaat. Symfony doet dan al het voorwerk.

Koppel je formulier aan het object

Omdat we de Entity pas gemaakt hebben nadat we het formulier hebben gemaakt moeten we even de zaken even aan elkaar knopen. Ga daarvoor naar src/Form/FormulierType.php en voeg de volgende regels toe.

namespace App\Form;
// Hier wordt het object persoon toegevoegd (Entity)
+ use App\Entity\Persoon;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class FormulierType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('Naam', TextType::class)
            ->add('Email', EmailType::class)
        ;
    }
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            // En hier wordt Entity Persoon doorgegeven
                'data_class'=> Persoon::class,
        ]);
    }
}

Gebruik je object in de formuliercontroller

Nu is het tijd om je controller te gaan vertimmeren zodat je de gegevens uit het object kunt gaan gebruiken. Je zal namelijk altijd iets moeten gaan doen met de gegevens die je in een formulier invoert (controleren, opslaan enzovoort). Voeg simpelweg de volgende regels toe en je bent klaar!

namespace App\Controller;

//--Voeg hier de Entity Persoon toe die je zojuist hebt gemaakt
use App\Entity\Persoon;
use App\Form\FormulierType;
//--Voeg hier ook een Request Object toe
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class FormulierController extends AbstractController
{
    /**
     * @Route("/formulier", name="formulier")
     */
    //--Deze regel aanpassen, nu wordt het Request Object doorgegeven
    public function index(Request $request)
    {
        //-- En hier wordt het object aangemaakt!
        $persoon = new Persoon();
        $persoon->setNaam("Helemaal niks");
        $persoon->setEmail('niks@niks.nl');

        //-- En let hier op dat het formulier en het object mee worden gegeven aan het formulier
        $form = $this->createForm(FormulierType::class, $persoon);

        $form->handleRequest($request);

        //-- Hier wordt gekeken of het formulier is ingevuld, zo ja..
        if ($form->isSubmitted() && $form->isValid()) {
            //--Een bericht op het scherm
            $this->addFlash("Bericht","Data ingediend!");
            //--En dan bevat het object nu de ingevulde gegevens
            //  en kan je iets in een variabele zetten bv:
            // $name=$persoon->getNaam();
        }

        //-- En hier wordt het formulier en het object op het scherm getoverd
        return $this->render('formulier/index.html.twig', [
            'our_form' => $form->createView(),
            'persoon'=> $persoon,
        ]);
    }
}

Laat Twig werken met het object

Het object wordt nu doorgegeven aan je controller en je kan de ingevulde gegevens gewoon weer op het scherm toveren door het Twig bestand templates/formulier/index.html/twigiets aan te passen.

{% extends 'base.html.twig' %}

{% block title %}Symfony Test Formulier{% endblock %}

{% block body %}
    <div>
        {{ form_start(our_form) }}
        {{ form_widget(our_form) }}
        <input type="submit" value="Send" />

        {{ form_end(our_form) }}

    </div>
    Je ingevulde naam is: {{ persoon.naam }} <br>
    Je ingevulde email is: {{ persoon.email }}
    {{ dump() }}
{% endblock %}

Formulier opmaak

We hebben nu een nogal lelijk formulier en je wilt dit vast wel wat mooier op het scherm laten zien. Symfony kan je hier flink wat werk uit handen nemen door automatisch een opmaak toe te voegen. Meestal zal het voorkomen dat je een globale layout voor al je formulieren in je applicatie wilt, je kan echter ook per formulier een layout toevoegen.

  • Kies een formulierthema op deze pagina.
  • Maak een keuze en download het thema wat je wilt hebben.
  • Plaats een thema voor de hele applicatie in templates, en plaats een thema voor slechts een enkel formulier in bv templates/mijnFormulier.

Voorbeeld opmaak voor de hele applicatie:

# config/packages/twig.yaml
twig:
    form_themes: ['bootstrap_4_horizontal_layout.html.twig']
    # ...

Voorbeeld opmaak voor een enkel formulier in Twig:

{% form_theme form 'foundation_5_layout.html.twig' %}

Twig en je formulier

Met {{ form_widget(our_form) }} in je Twig bestand wordt je hele formulier op het scherm getoverd, maar je wilt denk ik wel wat meer controle hierover in de toekomst. Je kunt in plaats van form_widget onderstaande Twig functies gebruiken

Formuliervelden aanpassen

In je Twig bestand van ons formulier staat het inputveld nog in HTML. Laten we dit eens ter illustratie veranderen zodat het door Symfony wordt afgehandeld. In het kort komt het neer op het volgende:

  • Voeg een formulier veldtype toe in src/Form/FormulierType
  • Pas het Twig bestand aan.
  • Voila!
//### src/Form/FormulierType
namespace App\Form;
use App\Entity\Persoon;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class FormulierType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('Naam', TextType::class)
            ->add('Email', EmailType::class)
            //### De toevoeging , ['attr'=>['class'=>'save']] is een (voorbeeld)class die wordt meegegeven
            //### Je kan dit checken door naar de paginabron te kijken in je browser
            //### Je kunt veel meer meegeven, bekijk hiervoor de documentatie.
            ->add('Opslaan', SubmitType::class, ['attr'=>['class'=>'save']])
        ;
    }
Form Types Reference