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

Webform Cookbook

How to support conditional Logic with multiple forms on the same page

Last updated on
27 October 2020

Conditional logic on a single page does not distinguish between multiple webforms on the same page.

The below code snippet adds a unique 'data-state-id' attribute to all webforms and prefix every #states selector with this unique 'data-state-id' attribute.
 

use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormStateInterface;
use Drupal\webform\Utility\WebformFormHelper;
use Drupal\webform\Utility\WebformArrayHelper;

/**
 * Implements hook_webform_submission_form_alter().
 */
function CUSTOM_MODULE_webform_submission_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  // Get unique states id for each webform.
  $unique_id = Html::getUniqueId($form_id);

  // Add unique states id as prefix the form.
  $form['#attributes']['data-states-id'] = $unique_id;

  // Get unique states id prefix that need to prepended to every #states selector.
  $unique_prefix = '[data-states-id="' . $unique_id . '"]';

  $elements =& WebformFormHelper::flattenElements($form);
  foreach ($elements as &$element) {
    if (!isset($element['#states'])) {
      continue;
    }

    foreach ($element['#states'] as &$triggers) {
      if (WebformArrayHelper::isSequential($triggers)) {
        foreach ($triggers as &$sub_triggers) {
          if (is_array($sub_triggers))
            $sub_triggers = _CUSTOM_MODULE_webform_submission_form_alter_add_unique_id_to_states($sub_triggers, $unique_prefix);
        }
      }
      else {
        if (is_array($triggers))
          $triggers = _CUSTOM_MODULE_webform_submission_form_alter_add_unique_id_to_states($triggers, $unique_prefix);
      }
    }
  }
}

/**
 * Add unique prefix to all :input #states selectors.
 *
 * @param array $array
 *   An associative array.
 * @param string $prefix
 *   Unique prefix to be prepended all :input #states selectors.
 *
 * @return array
 *   An associative array with unique prefix added to all :input
 *   #states selectors.
 */
function _CUSTOM_MODULE_webform_submission_form_alter_add_unique_id_to_states(array $array, $prefix) {
  $prefixed_array = [];
  foreach ($array as $key => $value) {
    if (strpos($key, ':input') != 0) {
      $key = $prefix . $key;
    }
    elseif (strpos($key, ':input') === 0) {
      $key = $prefix . ' ' . $key;
    }
    $prefixed_array[$key] = $value;
  }
  return $prefixed_array;
}

Help improve this page

Page status: No known problems

You can: