Ajouter un gestionnaire de soumission personnalisé à un formulaire

19

Comment puis-je ajouter un gestionnaire de soumission de formulaire personnalisé?

J'ai essayé d'ajouter $form['#submit'][] = 'mymodule_form_submit';ou $form['actions']['submit']['#submit'][] = 'mymodule_form_submit';de hook_form_alter().

use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\HttpFoundation\Request;

function MYMODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'node_trends_form' || $form_id == 'node_trends_edit_form') {
    foreach (array_keys($form['actions']) as $action) {
      if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
        $form['actions']['submit']['#submit'][] = 'mymodule_form_submit';
      }
    }
  }
}
function mymodule_form_submit(array $form, FormStateInterface $form_state){
    //die("why won't this execute? :(");
    drupal_set_message("Why won't this message show?");
}

Il ne semble drupal_set_message()pas être appelé. J'ai également essayé de reconstruire le cache, mais la fonction n'est toujours pas appelée.

J'utilise Drupal 8.2.3.

Yusef
la source
Vous devriez montrer l'implémentation complète de hook_form_alter(), ou c'est un peu plus difficile de vous dire ce que vous faites mal. Vous devez également indiquer la forme que vous essayez de modifier.
kiamlaluno
@kiamlaluno J'ajoute mon hook_form_alter.
Yusef
quel est encore votre code $ form ['actions'] ['submit'] ['# submit']? Essayez de remplacer ['submit'] par [$ action].
MrD

Réponses:

25

Si vous utilisez hook_form_node_form_alter()peut être utiliser un exemple de code :

function mymodule_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  foreach (array_keys($form['actions']) as $action) {
    if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
      $form['actions'][$action]['#submit'][] = 'mymodule_form_submit';
    }
  }
}

et soumettre une fonction

function mymodule_form_submit(array $form, FormStateInterface $form_state){
    //die("I'm not getting run, why :(");
    drupal_set_message("Why won't this message show?");

}
MrD
la source
1
$form['actions'][$action]['#submit'][]quelle documentation consultez-vous? ou avez-vous fait une faute de frappe? Dans ce document hook_form_alter, il est dit $form['actions']['submit']['#submit'][].
Pas de Sssweat
1
Intéressant, ouais peut-être qu'il a besoin de parcourir les actions. Bien que, dans cet autre Q Comment implémentez-vous un gestionnaire de soumission personnalisé dans hook_form_alter ()? c'est supposé fonctionner comme il le fait.
Pas de Sssweat
3
Chaque formulaire a des structures différentes. Il n'y a donc pas de réponse précise.
MrD
5
Voir drupal.org/node/1901216 et drupal.org/node/2068063 pour plus de contexte sur la raison pour laquelle cette boucle est nécessaire
Berdir
18

Création d'un plugin de gestion de formulaire Web personnalisé pour drupal 8.

Ce document suppose que vous avez déjà installé et activé webform et webform-ui

1) Créez votre formulaire Web. - Allez dans la structure -> formulaires Web et appuyez sur le bouton "+ Ajouter un formulaire Web". - Vous pouvez soit utiliser l'interface utilisateur ou utiliser yaml, cela dépend de vous. exemple yaml pour un formulaire à un champ qui prend une adresse e-mail:

email:
  '#type': email
  '#title': email
  '#title_display': invisible
  '#placeholder': 'ENTER YOUR EMAIL'
  '#attributes':
    class:
      - my-ip

L'indentation est importante pour yaml alors assurez-vous de bien faire les choses. les retraits sont des espaces.

Enregistrez maintenant votre formulaire.

2) Création d'un plugin de gestion de formulaire Web

Ensuite, nous pouvons créer un nouveau plugin qui apparaîtra dans la section "Emails / Handlers" lors de la modification du formulaire Web. Je l'appellerai myhandler, vous pouvez l'appeler comme vous voulez, à condition de remplacer toutes les mentions de myhandler par le nom que vous choisissez.

a) Créez un nouveau dossier pour votre plugin, faites-le dans votre racine drupal (appelé ici / var / www / html /) dans le sous-dossier suivant: / var / www / html / modules / Custom / myhandler

b) Créer un nouveau fichier dans le répertoire ci-dessus appelé myhandler.info.yml dans ce fichier va comme suit:

name: My Form Handler
description: handles form submits, does something with them. 
package: Custom
type: module
version: 1.0
core: 8.x

3) Créez un répertoire src dans le répertoire de votre module, par exemple: / var / www / html / modules / Custom / myhandler / src dans src create Plugin dans Plugin create WebformHandler

(cela peut être réalisé en une seule fois en utilisant

mkdir -p /var/www/html/modules/Custom/myhandler/src/Plugin/WebformHandler/ 

ce qui rendra la structure entière en une seule fois en utilisant le drapeau -p pour mkdir.)

4) Créez un nouveau fichier /var/www/html/modules/Custom/myhandler/src/Plugin/WebformHandler/MyFormHandler.php

dans ce fichier contient le code php suivant, j'ai laissé la configuration du formulaire de configuration afin que vous puissiez voir comment configurer votre plugin si nécessaire.

<?php
namespace Drupal\myhandler\Plugin\WebformHandler;

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Serialization\Yaml;
use Drupal\Core\Form\FormStateInterface;
use Drupal\webform\Plugin\WebformHandlerBase;
use Drupal\webform\webformSubmissionInterface;


/**
 * Form submission handler.
 *
 * @WebformHandler(
 *   id = "myhandler_form_handler",
 *   label = @Translation("MyHandler form handler"),
 *   category = @Translation("Form Handler"),
 *   description = @Translation("Do something extra with form submissions"),
 *   cardinality = \Drupal\webform\Plugin\WebformHandlerInterface::CARDINALITY_SINGLE,
 *   results = \Drupal\webform\Plugin\WebformHandlerInterface::RESULTS_PROCESSED,
 * )
 */
class MyFormHandler extends WebformHandlerBase {

     /**
       * {@inheritdoc}
       */

     public function defaultConfiguration() {
        return [
            'submission_url' => 'https://api.example.org/SOME/ENDPOINT',
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
        $form['submission_url'] = [
            '#type' => 'textfield',
            '#title' => $this->t('Submission URL to api.example.org'),
            '#description' => $this->t('The URL to post the submission data to.'),
            '#default_value' => $this->configuration['submission_url'],
            '#required' => TRUE,
        ];
        return $form;
    }



  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission) {
    // Your code here.
        // Get an array of the values from the submission.

        $values = $webform_submission->getData();

        // Get the URL to post the data to.
        $post_url = $this->configuration['submission_url'];

        $message = "MyHandler got form data:".print_r($values,1); 
        \Drupal::logger('myformhandler')->error($message);

        return true;
 }
}   
?>

5) Activez votre module MyHandler (en utilisant le menu drush ou extend) puis reconstruisez votre cache drupal ("drush cr" de n'importe où sous votre racine drupal (/ var / www / html ici) le ferait si vous utilisez drush)

6) éditez votre formulaire Web, allez dans "E-mail / Gestionnaires" et cliquez sur le bouton "+ Ajouter un gestionnaire" Vous devriez voir votre plugin répertorié, cliquez sur Ajouter un gestionnaire, vous devriez maintenant voir une boîte demandant l'url de soumission. cliquez sur le bouton Enregistrer. Si quelque chose ne semble pas correct ou ne fonctionne pas, consultez le journal des erreurs Apache, vous y trouverez peut-être quelque chose d'utile.

7) Testez votre formulaire - faites une soumission au formulaire, puis vérifiez le journal de surveillance (drush ws), vous devriez voir les valeurs qui lui sont envoyées. Ils peuvent être tronqués dans la sortie que vous voyez, pas de panique, tout est là. Ce que vous en faites maintenant dépend de vous.

J'espère que cela aide quelqu'un. Je l'ai bricolé à partir de trucs que j'ai trouvés autour de l'endroit et l'ai écrit dans un seul document. Merci aux autres qui m'ont amené ici.

CptnObvious
la source
1
Si je comprends bien, la seule chose mineure qui manque dans le code ci-dessus pour que le gestionnaire fonctionne correctement est la méthode submitConfigurationForm (), composée de parent::submitConfigurationForm($form, $form_state);et parent::applyFormStateToConfiguration($form_state);.
Hendrik
1
@Hendrik Non, vous n'en avez pas besoin. J'ai créé un nouveau gestionnaire avec seulement une submitForm()fonction et cela fonctionne. Toutes les autres fonctions sont situées dans la classe de base et je n'ai pas besoin de les remplacer. Soit dit en passant: une solution simple et assez agréable une fois que vous avez
compris
5

si vous utilisez hook_form_BASE_FORM_ID_alter dans Drupal 8 core 8.4.3, j'ai trouvé que les moyens d'ajouter le gestionnaire de soumission personnalisé ne fonctionnaient pas. Cela a fonctionné pour ajouter le nom de la fonction de gestionnaire de soumission:

$form['#submit'][] = 'mymodule_submit_handler';

Dans une autre situation, en utilisant hook_form_FORM_ID_alter dans Drupal 8.4.5, j'ai trouvé que ce qui précède ne fonctionnait pas pour ajouter le gestionnaire de soumission personnalisé. Au lieu de cela, cela a fonctionné:

$form['actions']['submit']['#submit'][]  = 'mymodule_submit_handler';
Anthony Fournier
la source
1

La réponse acceptée n'a pas fonctionné pour moi en utilisant Drupal 8.7.7, en essayant d'ajouter un gestionnaire de soumission à un formulaire du search_apimodule.

J'ai eu cette erreur:

TypeError: Argument 2 passed to _my_module_search_api_form_submit() must be an instance of FormStateInterface, instance of Drupal\Core\Form\FormState given in ...

Pour le faire fonctionner, j'ai changé ma signature de fonction en espace de noms complet de l'interface:

function _my_module_search_api_form_submit(array $form, Drupal\Core\Form\FormStateInterface $form_state) { ...
user1359
la source