Formulaire réutilisable

Plutôt que de définir le formulaire dans le contrôleur et donc limiter son usage à ce seul composant, on préférera le créer dans une classe dédiée.

La classe hérite d' AbstractType et définira la méthode buildForm .

<?php

namespace App\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;

class ProfileType extends AbstractType
{
	public function buildForm(FormBuilderInterface $builder, array $options)
	{
		$builder->add('id', TextType::class)
            ->add('titre', TextType::class)
            ->add('date', DateType::class)
            ->add('contenu', TextareaType::class)
	}
	
	public function getBlockPrefix()
	{
		return 'ProfileForm';
	}
}

?>

La fonction getBlockPrefix est utilisée pour le préfixe servant à identifier le formulaire et les champs qui le composent.

Il suffit ensuite de faire appel au formulaire dans notre contrôleur

// src/Controller/ProfileController
public function plusAction()
{
	$profile = new Profile();
	// On définit les options
	$options = array('action' => $this->generateUrl('lpars_cours_formulaires_plus'));
	// Génération du formulaire
	$form = $this->createForm(ProfileType::class, $diablo, $options);

	return $this->render('Profile:add.html.twig', array(
			'form' => $form->createView()));
}

Validation

La validation se fait directement dans les propriétés de l'objet, à travers les contraintes fixées dans la méthode loadValidatorMetadata .

Les contraintes sont dans les classes définies dans l'espace de nom Symfony\Component\Validator\Constraints\ .

PHP

public static function loadValidatorMetadata(ClassMetadata $metadata)
{
	$metadata->addPropertyConstraint('titre', new Length(
				array('min' => 5, 'minMessage' => 'Titre trop court', 
					'max' => 140, 'maxMessage' => 'Titre trop long')));
}

Twig

On peut afficher les erreur propres à un champ au sein du formulaire

{{ form_errors(form.titre) }}
{{ form_widget(form.titre, { 'attr':{'placeholder': 'Titre' }}) }}

Exemple

Les contraintes sont explicitées dans la documentation Symfony

Aller plus loin

Appel à un autre formulaire

On peut appeler un formulaire à l'intérieur du builder d'un formulaire.

  public function buildForm(FormBuilderInterface $builder, array $options)
  {
    $builder
      ->add('champ',        TextType::class)
      ->add('otherForm',        new NiceFormType())
    ;
  }

Héritage

Les formulaires sont des objets et peuvent donc être déclinés à travers l'héritage afin d'en changer le comportement (modifier les champs, validation, etc).

<?php

namespace App\Controller;

use Symfony\Component\Form\FormBuilderInterface;

class ProfileReducedType extends ProfileType {
	public function buildForm(FormBuilderInterface $builder, array $options) {
		// On fait appel à la méthode buildForm du parent
		parent::buildForm ( $builder, $options );
		
		// On supprime les champs gérés en interne
		$builder->remove ( 'date' );
		$builder->remove ( 'id' );
	}
	public function getBlockPrefix() {
		return 'ProfileReducedForm';
	}
}

?>	
Exemple