Anthony HERVÉ

Ingénieur édudes et développement

Drupal 8 - Créer un formulaire et un bloc

12/12/2016
Image actualité

Une action assez fréquente à faire lorsqu'on utilise Drupal est de créer des formulaires. Nous allons donc créer deux formulaires, un pour un formulaire standard et un pour uin formulaire de configuration. En dernier, nous créerons un bloc pour afficher notre formulaire.

Création d'un formulaire de base

Génération de la classe

Comme dans mon article précédent, vous pouvez soit créer le formulaire de manière manuelle soit via la commande drupal. Celle-ci met à dispositon l'action generate:form.

La classe générée est la suivante (dans src/Form) :

<?php

/**
 * @file
 * Contains \Drupal\monmodule\Form\MyForm.
 */

namespace Drupal\monmodule\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Class MyForm.
 *
 * @package Drupal\monmodule\Form
 */
class MyForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'my_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {

  }

}

Comme vous pouvez le voir, notre classe étend la classe FormBase de Drupal qui sert à gérer les formulaires. Cette classe comporte 3 fonctions :

  • getFormId : retoune l'identifiant du formulaire ;
  • buildForm : méthode appelée pour construire les formulaires, c'est là que l'on va mettre nos champs ;
  • submitForm : méthode appelée lors du clic sur le bouton de soumission de formulaire (après validation), c'est là que l'on va traiter les données.

Il en manque une que nous allons voir ensuite, mais qui est importante aussi.

  • validateForm : méthode appelée juste avant submitForm qui va permettre de valider les données envoyées

Création des champs

Dans la méthode buildForm, vous pouvez ajouter tous les champs que vous souhaitez comme ceci :

public function buildForm(array $form, FormStateInterface $form_state)
    {

        $form['name'] = array(
            '#type'               => 'textfield',
            '#title'              => 'Nom',
            '#required'           => true,
            '#wrapper_attributes' => ['class' => 'col-md-6 col-xs-12']
        );
        $form['comment'] = array(
            '#type'               => 'textarea',
            '#maxlength'          => 64,
            '#size'               => 64,
            '#required'           => true,
            '#title_display'      => false,
            '#placeholder'        => 'Commentaire',
            '#wrapper_attributes' => ['class' => 'col-md-3 col-xs-6'],
            '#id'                 => 'comment'
        );
        $form['submit'] = array(
            '#type'        => 'submit',
            '#value'       => 'Envoyer le commentaire',
            '#button_type' => 'primary',
            '#id'          => 'submit-btn'
        );

        return $form;
    }

Je vous invite à lire le lien suivant pour connaître un peu tous les types de champs proposés : https://api.drupal.org/api/drupal/elements.

Vous avez dans l'exemple un bref aperçu des options que l'on peut mettre pour créer un champ. Dans le lien que je viens de vous fournir, vous pouvez cliquer sur le nom des classes pour connaître les options pour ce type de champ.

Validation un formulaire

Dans votre classe, ajouter le méthode suivante :

public function validateForm(array &$form, FormStateInterface $formState)
    {
        // Check if name contains 3 chars
        if (strlen($formState->getValue('name')) < 3) {
            $formState->setErrorByName('name', 'Le nom doit avoir 3 caractères minimum.');
        }
    }

Cela vous permet de vérifier vos champs et d'ajouter éventuellement des erreurs. Si votre formulaire contient des erreurs, il ne passera jamais par submitForm.

Soumission du formulaire

La méthode submitForm gère la soumission du formulaire et vous permet notammeent de rediriger l'utilisateur vers la page que vous souhaitez après traitement du formulaire.

public function submitForm(array &$form, FormStateInterface $formState)
    {
        $formState->setRedirect(
            'url_redirect',
            array(
                'name'      => $formState->getValue('name')
            )
        );
    }

Création d'un formulaire de configuration

Lancer la commande suivante pour générer un formulaire de configuration.

drupal generate:form:config

<?php

/**
 * @file
 * Contains Drupal\monmodule\Form\SettingsForm.
 */

namespace Drupal\monmodule\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Class SettingsForm.
 *
 * @package Drupal\monmodule\Form
 */
class SettingsForm extends ConfigFormBase {

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return [
      'monmodule.settings',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'settings_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('monmodule.settings');
    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    parent::validateForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    parent::submitForm($form, $form_state);

    $this->config('monmodule.settings')
      ->save();
  }

}

Il ne reste plus qu'à ajouter les champs (buildForm) et à les traiter (submitForm).

public function buildForm(array $form, FormStateInterface $form_state)
    {
        $config = $this->config('monmodule.settings');
        $form['param'] = [
            '#type'          => 'textfield',
            '#title'         => 'Paramètre',
            '#default_value' => $config->get('monmodule.param')
        ];

        return parent::buildForm($form, $form_state);
    }

    public function submitForm(array &$form, FormStateInterface $form_state)
    {
        parent::submitForm($form, $form_state);

        $this->config('monmodule.settings')
            ->set('monmodule.param', $form_state->getValue('param'))
            ->save();
    }

La commande vous a aussi créer une route (dans le fichier monmodule.routing.yml) permettant d'afficher ce formulaire dans l'administration de Drupal, ainsi qu'un menu (dans le fichier monmodule.links.menu.yml).

Ce menu, appelé SettingsForm dans mon exemple, s'est ajouté par défaut dans Configuration > System.

Création d'un block

Un autre élément très immportant dans Drupal : les blocs. Même méthode que pour les formulaires, on utilise la commande Drupal.

drupal generate:plugin:block

La classes générée se trouve dans src/Plugin/Block.

<?php

/**
 * @file
 * Contains \Drupal\monmodule\Plugin\Block\MyBlock.
 */

namespace Drupal\monmodule\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
 * Provides a 'MyBlock' block.
 *
 * @Block(
 *  id = "my_block",
 *  admin_label = @Translation("My block"),
 * )
 */
class MyBlock extends BlockBase {


  /**
   * {@inheritdoc}
   */
  public function build() {
    $build = [];
    $build['my_block']['#markup'] = 'Implement MyBlock.';

    return $build;
  }

}

L'annotation @Block permet à Drupal de savoir que cette classe est un bloc. Une seule fonction est nécessaire, il s'agit de build qui, comme les controllers, renvoie un tableau de paramètre pour le template.

Votre bloc est maintenant disponible quand vous voulez placer un bloc dans le menu Structure > Block layout.

Afficher le formulaire dans le block

Au lieu de renvoyer un template pour le bloc, on peut aussi lui renvoyer un formulaire.

public function build()
    {
        return \Drupal::formBuilder()->getForm('Drupal\monmodule\Form\MyForm');
    }

Maintenant, j'ajoute mon super bloc dans la région Content.

Et hop, voici le résultat :

 

Alors, il est pas beau notre formulaire dans notre bloc ??? :-D

Commentaires