Lorsqu'un utilisateur final soumet des données saisies dans un formulaire Web Drupal 8, j'aimerais que mon module personnalisé modifie un champ qui se trouve sur le même formulaire en fonction des valeurs des autres champs. J'ai difficulté à accéder aux valeurs des données soumises et à définir également la valeur du champ que je souhaite modifier avant d'être enregistré.
Il y a un exemple de fichier API de formulaire Web inclus qui a des démarreurs pour les hooks. Un crochet que j'ai trouvé peut être utile est le suivant.
function hook_webform_submission_form_alter(array &$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {}
J'ai utilisé la dpm()
pour imprimer les valeurs de ces variables. La variable $form_state
Contient les données soumises et je sais que je peux utiliser la variable $form
Pour modifier ces valeurs avant d'être enregistrées.
Comment puis-je obtenir les valeurs des données soumises et également définir la valeur d'un autre champ sur cette même page avant d'enregistrer la soumission? Dans Drupal 7, c'était assez simple, mais avec Drupal 8 la navigation dans les structures de tableaux et d'objets des variables n'est pas aussi transparente).
Vous pouvez utiliser la méthode preSave
dans votre gestionnaire. Veuillez consulter le module de tests du gestionnaire de module Webform qui fait partie de la base de code Webform, il a TestWebformHandler.php
fichier qui définit le gestionnaire de test de soumission qui affiche un message d'état pour chaque événement de gestionnaire.
Par exemple:
<?php
namespace Drupal\webform_test_handler\Plugin\WebformHandler;
use Drupal\Core\Form\FormStateInterface;
use Drupal\webform\Plugin\WebformHandlerBase;
use Drupal\webform\WebformInterface;
use Drupal\webform\WebformSubmissionInterface;
/**
* Webform submission test handler.
*
* @WebformHandler(
* id = "test",
* label = @Translation("Test"),
* category = @Translation("Testing"),
* description = @Translation("Tests webform submission handler behaviors."),
* cardinality = \Drupal\webform\Plugin\WebformHandlerInterface::CARDINALITY_SINGLE,
* results = \Drupal\webform\Plugin\WebformHandlerInterface::RESULTS_IGNORED,
* submission = \Drupal\webform\Plugin\WebformHandlerInterface::SUBMISSION_REQUIRED,
* )
*/
class TestWebformHandler extends WebformHandlerBase {
/**
* {@inheritdoc}
*/
public function preCreate(array $values) {
$this->displayMessage(__FUNCTION__);
}
/**
* {@inheritdoc}
*/
public function postCreate(WebformSubmissionInterface $webform_submission) {
$this->displayMessage(__FUNCTION__);
}
/**
* {@inheritdoc}
*/
public function postLoad(WebformSubmissionInterface $webform_submission) {
$this->displayMessage(__FUNCTION__);
}
/**
* {@inheritdoc}
*/
public function preDelete(WebformSubmissionInterface $webform_submission) {
$this->displayMessage(__FUNCTION__);
}
/**
* {@inheritdoc}
*/
public function postDelete(WebformSubmissionInterface $webform_submission) {
$this->displayMessage(__FUNCTION__);
}
/**
* {@inheritdoc}
*/
public function preSave(WebformSubmissionInterface $webform_submission) {
$this->displayMessage(__FUNCTION__);
}
/**
* {@inheritdoc}
*/
public function postSave(WebformSubmissionInterface $webform_submission, $update = TRUE) {
$this->displayMessage(__FUNCTION__, $update ? 'update' : 'insert');
}
}
Ensuite, vous pouvez utiliser un moyen standard de modifier votre $webform_submission
.
Voir aussi: Manière de faire une action après la création d'une soumission de formulaire Web .
Après de nombreux essais et erreurs, j'ai trouvé une réponse à l'aide de ces pages:
https://www.drupal.org/node/2841729
https://www.drupal.org/node/2637958
L'idée est de créer un module personnalisé et d'ajouter une fonction de validation à l'aide de hook_form_alter()
. La fonction de validation définit ensuite les valeurs avant que le formulaire soit enregistré de manière permanente avec la méthode setValues()
.
Ici, je définis l'élément Webform observations
sur une valeur arbitraire.
function MYMODULE_form_alter(&$form,$form_state, $form_id) {
if ($form_id == 'MYFORM') {
$form['actions']['submit']['#validate'][] = 'MYMODULE_operation_form_validate';
}
}
function MYMODULE_operation_form_validate(&$form, $form_state, $form_id) {
$values = ['observations' => 777];
$form_state->setValues($values);
}
Dans Drupal 8 vous pouvez utiliser hook_ENTITY_TYPE_presave
, par exemple:
/**
* Implements hook_ENTITY_TYPE_presave().
*/
function mymodule_webform_submission_presave(\Drupal\webform\Entity\WebformSubmission $submission) {
// var_dump($submission); exit;
}
afin d'accéder, valider ou modifier les éléments de votre webform $submission
.
Pour Drupal 7, voir: Comment modifier les informations de soumission du formulaire Web .
Utilisez ce crochet hook_webform_element_alter
/**
* Implements hook_webform_element_alter().
*
* @param array $element
* @param FormStateInterface $form_state
* @param array $context
*/
function module_webform_element_alter(array &$element, FormStateInterface $form_state, array $context) {
//use kint
kint($element);
//alter location field
if ($element['#webform_id'] === 'my_form--location') {
//do the logic
}
}
Bingo!
Il existe plusieurs façons de le faire. Vous pouvez utiliser: -
1. crochet_webform_element_alter ()
function your_module_name_webform_element_alter(array &$element, FormStateInterface $form_state, array $context) {
if (isset($element['#webform_id'])){
if ($element['#webform_id'] === 'abc') {
//do the logic
}
}
}
Suivez ceci pour une meilleure compréhension https://www.drupal.org/docs/8/modules/webform/webform-cookbook/how-to-add-custom-validation-to-a-webform-element =
2.hook_form_alter ()
function your_module_name_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'your_form_id') {
$form['#validate'][] = 'your_module_name_form_validate';
}
}
Et votre logique entre en fonction de validation
function your_module_name_form_validate($form, &$form_state) {
$values = $form_state->getValues();
//Your logic goes here.
}
function your_module_name_webform_submission_presave(EntityInterface $entity) {
// Entity new will only allow you to modify the value for first time.
if ($entity->isNew()) {
$entity->setElementData('key', value);
}
}