Custom Form Types in Symfony
Custom Form Types in Symfony
~14 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Über einfache Text-Felder hinaus bietet Symfony vorgefertigte Feldtypen für wiederkehrende Muster – wir modellieren jetzt das Aufgaben-Formular mit Status-Auswahl und Fälligkeitsdatum.
ChoiceType für feste Auswahllisten
<?php
declare(strict_types=1);
namespace App\Form\Data;
use Symfony\Component\Validator\Constraints as Assert;
class TaskData
{
#[Assert\NotBlank(message: 'Bitte geben Sie einen Titel ein.')]
public string $titel = '';
#[Assert\Choice(choices: ['offen', 'in_arbeit', 'erledigt'])]
public string $status = 'offen';
#[Assert\GreaterThanOrEqual('today', message: 'Das Fälligkeitsdatum darf nicht in der Vergangenheit liegen.')]
public ?\DateTimeImmutable $faelligAm = null;
}<?php
declare(strict_types=1);
namespace App\Form;
use App\Form\Data\TaskData;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class TaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('titel', TextType::class, ['label' => 'Titel'])
->add('status', ChoiceType::class, [
'label' => 'Status',
'choices' => [
'Offen' => 'offen',
'In Arbeit' => 'in_arbeit',
'Erledigt' => 'erledigt',
],
])
->add('faelligAm', DateType::class, [
'label' => 'Fällig am',
'widget' => 'single_text',
'required' => false,
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(['data_class' => TaskData::class]);
}
}Bei ChoiceType ist die Array-Syntax ['Anzeigetext' => 'gespeicherter_wert'] WICHTIG: der SCHLÜSSEL erscheint im HTML als sichtbarer Text, der WERT wird tatsächlich gespeichert – leicht zu verwechseln beim ersten Mal.
'widget' => 'single_text' rendert das Datumsfeld als EIN einzelnes <input type="date"> – ohne diese Option würde Symfony standardmäßig DREI separate Dropdown-Felder für Tag/Monat/Jahr erzeugen, was für moderne Browser-Datepicker unnötig ist.
Einen eigenen, wiederverwendbaren Form Type bauen
Braucht MEHRERE Formulare dieselbe Feldkombination (z. B. "wähle einen Nutzer aus einer Dropdown-Liste" für sowohl Projekt-Mitglieder als auch Task-Zuweisung), lohnt sich ein EIGENER, wiederverwendbarer Form Type:
<?php
declare(strict_types=1);
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class UserChoiceType extends AbstractType
{
public function getParent(): string
{
return ChoiceType::class;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'choices' => [
// In Block 4 ersetzt durch eine echte Datenbank-Abfrage aller Nutzer
'Anna Schmidt' => 1,
'Ben Meier' => 2,
],
]);
}
}getParent() gibt an, dass UserChoiceType auf ChoiceType AUFBAUT – dadurch "erbt" er dessen komplettes Verhalten und MUSS nur die projektspezifischen Standardwerte definieren. Verwendung wie jeder andere Form Type: ->add('zugewiesenAn', UserChoiceType::class).
Tipp: In Block 4 (Kapitel 21) ersetzen wir die hartcodierte choices-Liste durch EntityType – einen speziellen ChoiceType, der die Optionen DIREKT aus der Datenbank lädt. Das Prinzip (eigener, wiederverwendbarer Form Type) bleibt identisch.