Advertising sustains the DA. Ads are hidden for members. Join today

Webform Cookbook

How To Pass Webform Submission Data to Javascript

Last updated on
4 November 2022

This page has not yet been reviewed by Webform Cookbook maintainer(s) and added to the menu.

Problem

There are cases where there is a need to perform additional operations when an AJAX webform is submitted.  Perhaps we would like to show a thank you modal containing the users first name after the form has been submitted or we may need to pass specific form data to a javascript function so additional processing can be done. 

Approach

We will focus on a use case where a form is submitted and the form submission data (in this case a field named first_name) is passed to a jQuery function for additional processing.

Solution

Step 1: Alter the ajax callback for the webform

In myajaxform.module we will alter the webform

use Drupal\Core\Form\FormStateInterface;

/**
 * Implements hook_webform_submission_form_alter().
 */
function myajaxform_webform_submission_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form['#webform_id'] == 'my_webform_id') {
    // Add an AJAX callback to the form submission.
    $form['actions']['submit']['#ajax'] = [
      'callback' => 'myajaxform_ajax_submission_callback',
    ];
  }
}

Step 2: Create our custom webform callback

This callback will be called when the form is submitted.  At this point we will continue to call the default AJAX form submission callback.

use Drupal\Core\Form\FormStateInterface;

/**
 * Form submission callback that invokes an arbitrary jquery method.
 */
function myajaxform_ajax_submission_callback(&$form, FormStateInterface $form_state) {

  /** @var \Drupal\webform\WebformSubmissionForm $form_object */
  $form_object = $form_state->getFormObject();

  // Call the default #ajax callback.
  // @see \Drupal\webform\Form\WebformAjaxFormTrait::submitAjaxForm
  $response = $form_object->submitAjaxForm($form, $form_state);
  return $response;
}

Step 3: Alter our webform callback to perform an action

By leveraging Drupal's AJAX Callbacks, we can perform many different operations on form submission.  Since we would like to perform an arbitrary action upon form submission we will use the InvokeCommand which will

Instruct the client to invoke the given jQuery method with the supplied arguments on the elements matched by the given selector. 

We pass it a selector (which can be NULL when the command is a response to a request from an #ajax form element), a jQuery method which we will define in step 4, and an optional array of arguments.  We can pass arbitrary data to the arguments and it will be available in our jQuery method.  In this case we will pass it the value of a make-believe first_name form field.

use Drupal\Core\Ajax\InvokeCommand;

/**
 * Form submission callback that invokes an arbitrary jquery method.
 */
function myajaxform_ajax_submission_callback(&$form, FormStateInterface $form_state) {

  /** @var \Drupal\webform\WebformSubmissionForm $form_object */
  $form_object = $form_state->getFormObject();

  // If errors, call the default #ajax callback.
  // @see \Drupal\webform\Form\WebformAjaxFormTrait::submitAjaxForm
  if ($form_state->hasAnyErrors()) {
    /** @var \Drupal\webform\Ajax\WebformSubmissionAjaxResponse $response */
    $response = $form_object->submitAjaxForm($form, $form_state);
  }
  
  // If there are no errors, call the default #ajax callback and then invoke AJAX callback.
  else {
    $first_name = $form_state->getValue('first_name');
    /** @var \Drupal\webform\Ajax\WebformSubmissionAjaxResponse $response */
    $response = $form_object->submitAjaxForm($form, $form_state);
    /** InvokeCommand($selector, $method, array $arguments = []) */
    $response->addCommand(new InvokeCommand(NULL, 'myCustomAjaxFormSubmit', [$first_name]));
  }
  
return $response;
}

Step 4: Define our jQuery method that will be invoked during form submission

$.fn.myCustomAjaxFormSubmit allows us to define a method (also called a plugin) that can be called throughout our codebase.  Here, we create a jQuery method that accepts an option (firstName).  This option contains the value of our form field first_name that we passed to InvokeCommand in step 3.

(function($, Drupal, drupalSettings) {
  Drupal.behaviors.my_custom_behavior = {
    attach(context, settings) {
      $.fn.myCustomAjaxFormSubmit = function(firstName) {
        var firstNameFromWebform = firstName;
        // Logs the value of the first_name field from our webform.
        console.log(firstNameFromWebform);
      };
    }
  };
})(jQuery, Drupal, drupalSettings);

Step 5: Define a library so our JS asset can be included on our form.

See Adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 module.

my_custom_behavior:
  version: VERSION
  js:
    js/my_custom_behavior.js: {}

Step 6: Attach our library to the webform.

We attach our library that includes the javascript to the webform. We are attaching it here in the same place we are are adding our custom Ajax callback.

use Drupal\Core\Form\FormStateInterface;

/**
 * Implements hook_webform_submission_form_alter().
 */
function myajaxform_webform_submission_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form['#webform_id'] == 'my_webform_id') {
    // Add an AJAX callback to the form submission.
    $form['actions']['submit']['#ajax'] = [
      'callback' => 'myajaxform_ajax_submission_callback',
    ];
    // Attach library to include custom behavior.
    $form['#attached']['library'][] = "myajaxform/my_custom_behavior";
  }
}

Step 7: Create an .info.yml file for the module 

Add an .info.yml file called myajaxform.info.ymlso Drupal can "see" your module.

See "Let Drupal know about your module with an .info.yml file" for more detailed information on .info.yml files.

name: My Ajax Form
description: Creates an ajax callback for a webform.
package: Custom

type: module
core: 8.x

dependencies:
  - webform:webform

Full files

myajaxform.info.yml

name: My Ajax Form
description: Creates an ajax callback for a webform.
package: Custom

type: module
core: 8.x

dependencies:
  - webform:webform

myajaxform.module

<?php

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\InvokeCommand;

/**
 * Implements hook_webform_submission_form_alter().
 */
function myajaxform_webform_submission_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form['#webform_id'] == 'my_webform_id') {
    // Add an AJAX callback to the form submission.
    $form['actions']['submit']['#ajax'] = [
      'callback' => 'myajaxform_ajax_submission_callback',
    ];
    // Attach library to include custom behavior.
    $form['#attached']['library'][] = "myajaxform/my_custom_behavior";
  }
}

/**
 * Form submission callback that invokes an arbitrary jquery method.
 */
function myajaxform_ajax_submission_callback(&$form, FormStateInterface $form_state) {

  /** @var \Drupal\webform\WebformSubmissionForm $form_object */
  $form_object = $form_state->getFormObject();

  // If errors, call the default #ajax callback.
  // @see \Drupal\webform\Form\WebformAjaxFormTrait::submitAjaxForm
  if ($form_state->hasAnyErrors()) {
    /** @var \Drupal\webform\Ajax\WebformSubmissionAjaxResponse $response */
    $response = $form_object->submitAjaxForm($form, $form_state);
  }
  
  // If there are no errors, call the default #ajax callback and then invoke AJAX callback.
  else {
    $first_name = $form_state->getValue('first_name');
    /** @var \Drupal\webform\Ajax\WebformSubmissionAjaxResponse $response */
    $response = $form_object->submitAjaxForm($form, $form_state);
    /** InvokeCommand($selector, $method, array $arguments = []) */
    $response->addCommand(new InvokeCommand(NULL, 'myCustomAjaxFormSubmit', [$first_name]));
  }
  
return $response;
}

myajaxform.libaries.yml

my_custom_behavior:
  version: VERSION
  js:
    js/my_custom_behavior.js: {}

my-ajax-form-processing.js

(function($, Drupal, drupalSettings) {
  Drupal.behaviors.my_custom_behavior = {
    attach(context, settings) {
      $.fn.myCustomAjaxFormSubmit = function(firstName) {
        var firstNameFromWebform = firstName;
        // Logs the value of the first_name field from our webform.
        console.log(firstNameFromWebform);
      };
    }
  };
})(jQuery, Drupal, drupalSettings);

Help improve this page

Page status: No known problems

You can: