You are here

public static function WebformComputedBase::processWebformComputed in Webform 6.x

Same name and namespace in other branches
  1. 8.5 src/Element/WebformComputedBase.php \Drupal\webform\Element\WebformComputedBase::processWebformComputed()

Processes a Webform computed token element.

Parameters

array $element: The element.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

array $complete_form: The complete form structure.

Return value

array The processed element.

File

src/Element/WebformComputedBase.php, line 65

Class

WebformComputedBase
Provides a base class for 'webform_computed' elements.

Namespace

Drupal\webform\Element

Code

public static function processWebformComputed(&$element, FormStateInterface $form_state, &$complete_form) {
  $webform_submission = static::getWebformSubmission($element, $form_state, $complete_form);
  if ($webform_submission) {

    // Set tree.
    $element['#tree'] = TRUE;

    // Set #type to item to trigger #states behavior.
    // @see \Drupal\Core\Form\FormHelper::processStates;
    $element['#type'] = 'item';
    $value = static::computeValue($element, $webform_submission);
    static::setWebformComputedElementValue($element, $value);
  }
  if (!empty($element['#states'])) {
    if (!empty($element['#ajax'])) {

      // The element's #states must be place outside the
      // computed ajax wrapper.
      WebformElementHelper::fixStatesWrapper($element);
    }
    else {
      WebformFormHelper::processStates($element, '#wrapper_attributes');
    }
  }

  // Add validate callback.
  $element += [
    '#element_validate' => [],
  ];
  array_unshift($element['#element_validate'], [
    get_called_class(),
    'validateWebformComputed',
  ]);

  /**************************************************************************/

  // Ajax support

  /**************************************************************************/

  // Enabled Ajax support only for computed elements associated with a
  // webform submission form.
  if ($element['#ajax'] && $form_state
    ->getFormObject() instanceof WebformSubmissionForm) {

    // Get button name and wrapper id.
    $button_name = 'webform-computed-' . implode('-', $element['#parents']) . '-button';
    $wrapper_id = 'webform-computed-' . implode('-', $element['#parents']) . '-wrapper';

    // Get computed value element keys which are used to trigger Ajax updates.
    preg_match_all('/(?:\\[webform_submission:values:|data\\.|data\\[\')([_a-z0-9]+)/', $element['#template'], $matches);
    $element_keys = $matches[1] ?: [];
    $element_keys = array_unique($element_keys);

    // Wrapping the computed element is two div tags.
    // div.js-webform-computed is used to initialize the Ajax updates.
    // div#wrapper_id is used to display response from the Ajax updates.
    $element += [
      '#prefix' => '',
      '#suffix' => '',
    ];
    $element['#wrapper_id'] = $wrapper_id;
    $element['#prefix'] .= '<div class="js-webform-computed" data-webform-element-keys="' . implode(',', $element_keys) . '">' . '<div class="js-webform-computed-wrapper" id="' . $wrapper_id . '">';
    $element['#suffix'] = '</div></div>' . $element['#suffix'];

    // Add hidden update button.
    $element['update'] = [
      '#type' => 'submit',
      '#value' => t('Update'),
      '#validate' => [
        [
          get_called_class(),
          'validateWebformComputedCallback',
        ],
      ],
      '#submit' => [
        [
          get_called_class(),
          'submitWebformComputedCallback',
        ],
      ],
      '#ajax' => [
        'callback' => [
          get_called_class(),
          'ajaxWebformComputedCallback',
        ],
        'wrapper' => $wrapper_id,
        'progress' => [
          'type' => 'none',
        ],
      ],
      // Disable validation, hide button, add submit button trigger class.
      '#attributes' => [
        'formnovalidate' => 'formnovalidate',
        'class' => [
          'js-hide',
          'js-webform-computed-submit',
        ],
      ],
      // Issue #1342066 Document that buttons with the same #value need a unique
      // #name for the Form API to distinguish them, or change the Form API to
      // assign unique #names automatically.
      '#name' => $button_name,
    ];

    // Attached computed element Ajax library.
    $element['#attached']['library'][] = 'webform/webform.element.computed';
  }
  return $element;
}