9

When an end-user is submitting data entered in a Drupal 8 webform, I would like my custom module to modify a field that is on the same form based on values of other fields. I am having trouble accessing the values of the submitted data and also setting the value of the field that I wish to change before being saved.

There is a sample webform API file included which has some starters for hooks. A hook which I found may be useful is the following.

function hook_webform_submission_form_alter(array &$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {}

I used the dpm() to print the values of these variables. The $form_state variable has the data submitted, and I know I can use the $form variable to change these values before being saved.

How can I get values of the data submitted and also set the value of another field on that same page before the submission is saved? In Drupal 7 this was fairly straightforward, but with Drupal 8 navigating the array and object structures of variables is not as transparent.

5 Answers 5

7

You can use preSave method in your handler. Please check out the Webform module handler tests module which is part of Webform codebase, it has TestWebformHandler.php file which defines the submission test handler which displays a status message for every handler event.

For example:

<?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');
  }
}

Then you can use a standard ways of modifying your $webform_submission.

See also: Way to do an action after a webform submission has been created.

4

After much trial and error, I found an answer with the help of these pages:

https://www.drupal.org/node/2841729

https://www.drupal.org/node/2637958

The idea is to create a custom module and add a validation function using hook_form_alter(). The validation function then sets the values before the form is saved permanently with the setValues() method.

Here, I am setting the webform element observations to an arbitrary value.

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);
}
1
  • Thanks very much for this - I was getting very frustrated trying to find a hook to fire before the webform module purges $_POST. One thing I will point out however is that only the first 2 parameters get passed to the _validate function, so the inclusion of $form_id causes an undefined notice to be triggered.
    – Scoots
    Nov 27, 2019 at 12:19
4

In Drupal 8 you can use hook_ENTITY_TYPE_presave, for example:

/**
 * Implements hook_ENTITY_TYPE_presave().
 */
function mymodule_webform_submission_presave(\Drupal\webform\Entity\WebformSubmission $submission) {
  // var_dump($submission); exit;
}

in order to access, validate or modify the elements of your webform $submission.

See: How to track webform element create, update, and delete operations.

For Drupal 7, see: How to alter the Webform submission information.

2

Use this hook 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!

1

There are multiple ways of doing this.You can use :-

1.hook_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
    }
  }
}

Follow this for better understanding 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';
  }
}

And your logic goes into validate function

function your_module_name_form_validate($form, &$form_state) {
  $values = $form_state->getValues();
  //Your logic goes here.
}
  1. hook_ENTITY_TYPE_presave()
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);
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.