Utiliser et paramétrer les éléments de formulaire dans Drupal

Drupal 8

Utiliser et paramétrer les éléments de formulaire dans Drupal

Soumis par Antoine le mar 24/03/2020 - 10:50

L'article utiliser les formulaires décrit la procédure globale pour construire un formulaire. Dans cet article, nous allons voir plus précisément l'utilisation des éléments de formulaire qui permettent de générer des éléments html intégrés au formulaire comme des inputs, des textarea...

La documentation officielle liste sur une même page tous les éléments de rendu et de formulaires. Les éléments de formulaire utilisent la classe FormElement qui étend la classe RenderElement, qui étend elle même la classe PluginBase. La documentation officielle présente aussi une vue d'ensemble de l'api de rendu. N'hésitez pas à consulter les différentes classes pour trouver comment paramétrer vos éléments de formulaire.

Ajouter un élément dans un formulaire

Nous avons vu dans l'article utiliser les formulaires que le formulaire était généré grâce à la fonction buidForm dans le fichier src/Form/nomformulaire.php. Cette fonction retourne un tableau associatif $form dont les clés correspondent à des éléments de formulaire.

Le code suivant permet de générer un input de type "text" et un bouton "submit"

public function buildForm(array $form, FormStateInterface $form_state) {
    $form['montexte'] = array(
      '#type' => 'textfield',
      '#title' => $this
        ->t('A texte'),
    );
    $form['save'] = array(
      '#type' => 'submit',
      '#value' => $this
        ->t('Save'),
    );
    return $form;
  }

Comment savoir ce qu'il est possible de configurer dans un élément de formulaire ?

La première chose à faire est de trouver la classe de l'élément de formulaire sur cette page. N'hésitez pas à filtrer le tableau pour n'afficher que les formElement. Pour chaque élément de formulaire, il y a un lien vers la documentation de la classe. Ces pages présentent, entre autre, les différentes propriétés spécifiques à l'élément de formulaire. On peut voir que la classe Textfield dispose des propriétés maxlenght, size, pattern...

Vous trouverez aussi des propriétés communes à tous les formElement dans les pages de documentation des classes RenderElement et PluginBase.

Dans la suite de l'article, nous allons présenter des éléments peu courants ou difficile à configurer, et des paramétrages utiles :

Liste des éléments de formulaire

L'élément de formulaire tableselect

Générer un table select

Les tabletselect sont des tableaux qui contiennent une colonne avec des cases à cocher. Le tableau qui présente tous les contenus dans l'administration est un textselect. Les tables select doivent avoir les propriétés suivantes "#type: 'tableselect', '#header', '#options', '#empty'

La propriété "#header" doit contenir un tableau qui liste les entêtes de colonne. L'entête de la colonne des cases à cocher sera construit automatiquement, ce n'est pas la peine d'en produire un

La propriété "options" doit contenir un tableau associatif dont :

  • les clés sont les id des éléments placés dans chaque ligne.
  • Les valeurs sont elles aussi un tableau associatif qui doit contenir
    • optionnellement une clé '#attributes qui contient un tableau associatif avec des couple clés/valeur du type 'nom_attribut'=>['valeur1', 'valeur2'] 
    • obligatoirement une clé par title du header avec comme valeur, soit un élément simple comme du texte, soit un tableau associatif qui contient :
      • optionnellement une clé par attribut du type 'nom_attribut'=>['valeur1', 'valeur2'] 
      • obligatoirement une clé 'data' qui contient les valeurs de la cellule.

Le code suivant génère un tableselect avec des classes dans les th, tr, et td , ce que la doc officielle ne montre pas

$header = array(
      'id' => t('id'),
      'title' => [
        'class'=>['th-class1', 'th-class2'],
        'data'=>t('title'),
        ]
    );

$entities = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties(['type' => 'article']);

foreach ($entities as $entity) {
      // chaque ligne a pour clé l'identifiant de l'article
      $options[$entity->id()] = [

        //La clé #attributes permet d'ajouter des attributs à chaque tr
        '#attributes'=>[
          'class'=>['tr-class1, tr-class2'],
          'id'=>['tr-id-'.$entity->id()]
        ],
        // Exemple de cellule avec des dates et des attributs. La clé de la cellule doit correspondre à une clé du header
        'id' => [
          'class'=>['td-class1', 'td-class2'],
          'id'=>['td-id-'.$entity->id()],
          'data'=>$entity->id(),
          ],
        // Exemple de cellule avec juste une valeur. La clé de la cellule doit correspondre à une clé du header
        'title' => $entity->label(),
      ];
    }
$form['table'] = array(
      '#type' => 'tableselect',
      '#header' => $header,
      '#options' => $options,
      '#empty' => $this->t('Aucun article trouvé'),
      '#required'=>true
    );

Récupérer les valeurs d'un tableselect

Habituellement, dans les méthodes validateForm() et submitForm(), on récupère les valeurs avec la méthode $form_state->getValue('nom_form_element')

Pour les tables select, il y a une petite subtilité . La méthode $form_state->getValue('nom_table_select') renvoie toutes les lignes du table select. Pour obtenir uniquement les id des lignes cochées, il faut utiliser : array_filter($form_state->getValue('table')).

Paramétrer un élément de formulaire

Rendre un élément obligatoire

Il suffit de rajouter la clé '#required' =>true

Définir une valeur par défaut

Il faut rajouter la clé 'default_value'=>'la valeur par défaut'

Rendre un élément visible en fonction de la valeur saisie dans un autre champs

Imaginons que nous avons un formulaire qui propose entre autre de s'inscrire à une newsletter. Si l'utilisateur coche la case "J'accepte de recevoir la newletters" alors un input du type e-mail apparaît pour permettre la saisie de l'adresse mail. Pour faire cela, il faut :

  • nommer la case à cocher
  • définir un état (state) pour l'input email afin de le rendre visible dans certaines condition

Ce qui donne le code suivant :

$form['case']=array(
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Send me a email'),
      '#attributes' => [
        'name' => 'case',
      ],
    );

    $form['email'] = array(
      '#type' => 'email',
      '#title' => $this->t('Email'),
      '#pattern' => '*@example.com',
      '#states' => [
        //show this textfield only if the radio 'other' is selected above
        'visible' => [
          ':input[name="case"]' => ['checked' => true],
        ],
      ],
    );

Les différents états et conditions sont décrits dans la document sur la fonction drupal_process_state

Version