WebformAjaxElementTrait.php in Webform 6.x
Same filename and directory in other branches
Namespace
Drupal\webform\ElementFile
src/Element/WebformAjaxElementTrait.phpView source
<?php
namespace Drupal\webform\Element;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
/**
* Trait for ajax element support.
*
* @see \Drupal\webform_test_element\Plugin\WebformElement\WebformTestElementProperties
*/
trait WebformAjaxElementTrait {
/**
* Get Ajax element wrapper id.
*
* @param string $id
* A unique element id.
*
* @return string
* The element id suffixed with *-wrapper.
*/
public function getAjaxElementWrapperId($id) {
return $id . '-ajax-wrapper';
}
/**
* Get Ajax element update name.
*
* @param string $id
* A unique element id.
*
* @return string
* The element update name suffixed with *-update.
*/
public function getAjaxElementUpdateName($id) {
return str_replace('-', '_', $id) . '_ajax_update';
}
/**
* Get Ajax element update class.
*
* @param string $id
* A unique element id.
*
* @return string
* The element update classes prefixed with js-* and suffixed with *-update.
*/
public function getAjaxElementUpdateClass($id) {
return 'js-' . $id . '-ajax-update';
}
/**
* Build an Ajax element.
*
* @param string $id
* The id used to create the Ajax wrapper and trigger.
* @param array &$wrapper_element
* The element to be update via Ajax.
* @param array &$trigger_element
* The element to trigger the Ajax update.
* @param array|null &$update_element
* The element to append the hidden Ajax submit button.
*/
public function buildAjaxElement($id, array &$wrapper_element, array &$trigger_element, array &$update_element = NULL) {
static::buildAjaxElementWrapper($id, $wrapper_element);
static::buildAjaxElementTrigger($id, $trigger_element);
if ($update_element) {
static::buildAjaxElementUpdate($id, $update_element);
}
else {
static::buildAjaxElementUpdate($id, $wrapper_element);
}
}
/**
* Build an Ajax element's wrapper.
*
* @param string $id
* The id used to create the Ajax wrapper and trigger.
* @param array &$element
* The element to be update via Ajax.
*/
public function buildAjaxElementWrapper($id, array &$element) {
$element['#prefix'] = '<div id="' . $this
->getAjaxElementWrapperId($id) . '">';
$element['#suffix'] = '</div>';
$element['#attached']['library'][] = 'webform/webform.element.ajax';
$element['#webform_ajax_element_type'] = 'wrapper';
$element['#webform_ajax_element_id'] = $id;
}
/**
* Build an Ajax element's trigger.
*
* @param string $id
* The id used to create the Ajax wrapper and trigger.
* @param array &$element
* The element to trigger the Ajax update.
*/
public function buildAjaxElementTrigger($id, array &$element) {
$element['#attributes']['data-webform-trigger-submit'] = '.' . $this
->getAjaxElementUpdateClass($id);
$element['#webform_ajax_element_type'] = 'trigger';
$element['#webform_ajax_element_id'] = $id;
}
/**
* Build an Ajax element's update (submit) button.
*
* @param string $id
* The id used to create the Ajax wrapper and trigger.
* @param array &$element
* The element to append the hidden Ajax submit button.
*/
public function buildAjaxElementUpdate($id, array &$element) {
$element['update'] = [
'#type' => 'submit',
'#value' => t('Update'),
// Submit buttons with the same label must have a unique name.
// @see https://www.drupal.org/project/drupal/issues/1342066
'#name' => $this
->getAjaxElementUpdateName($id),
// Validate the element.
'#validate' => [
[
get_called_class(),
'validateAjaxElementCallback',
],
],
// Submit the element.
'#submit' => [
[
get_called_class(),
'submitAjaxElementCallback',
],
],
// Refresh the element.
'#ajax' => [
'callback' => [
get_called_class(),
'updateAjaxElementCallback',
],
'wrapper' => $this
->getAjaxElementWrapperId($id),
'progress' => [
'type' => 'fullscreen',
],
],
// Disable validation, hide the button, and add trigger update class.
'#attributes' => [
'formnovalidate' => 'formnovalidate',
'class' => [
'js-hide',
$this
->getAjaxElementUpdateClass($id),
],
],
// Always render the update button.
'#access' => TRUE,
// Store a reference to the Ajax id.
'#webform_ajax_element_type' => 'update',
'#webform_ajax_element_id' => $id,
];
}
/**
* Ajax element validate callback.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
public static function validateAjaxElementCallback(array $form, FormStateInterface $form_state) {
$button = $form_state
->getTriggeringElement();
if (empty($button['#limit_validation_errors'])) {
$form_state
->clearErrors();
}
}
/**
* Ajax element submit callback.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
public static function submitAjaxElementCallback(array $form, FormStateInterface $form_state) {
$form_state
->setRebuild();
}
/**
* Ajax element update callback.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @return array
* The properties element.
*/
public static function updateAjaxElementCallback(array $form, FormStateInterface $form_state) {
$button = $form_state
->getTriggeringElement();
$id = $button['#webform_ajax_element_id'];
// Check if the immediate parent element is the Ajax wrapper.
$element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -1));
if (isset($element['#webform_ajax_element_id']) && $element['#webform_ajax_element_id'] === $id && isset($element['#webform_type']) && $element['#webform_type'] === 'wrapper') {
return $element;
}
// Get the Ajax wrapper from the parent parent element.
$parent_element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -2));
return static::getAjaxElementWrapperRecursive($id, $parent_element);
}
/**
* Get ajax element wrapper.
*
* @param string $id
* The id used to create the Ajax wrapper and trigger.
* @param array $element
* An element or form containing the Ajax wrapper.
*
* @return array|null
* The Ajax wrapper element.
*/
protected static function getAjaxElementWrapperRecursive($id, array $element) {
if (isset($element['#webform_ajax_element_id']) && $element['#webform_ajax_element_id'] === $id && $element['#webform_ajax_element_type'] === 'wrapper') {
return $element;
}
foreach (Element::children($element) as $key) {
$ajax_element = static::getAjaxElementWrapperRecursive($id, $element[$key]);
if ($ajax_element) {
return $ajax_element;
}
}
return NULL;
}
}
Traits
Name | Description |
---|---|
WebformAjaxElementTrait | Trait for ajax element support. |