View source
<?php
namespace Drupal\webform\Plugin\WebformElement;
use Drupal\Core\Form\FormStateInterface;
use Drupal\webform\Utility\WebformElementHelper;
use Drupal\webform\WebformSubmissionInterface;
class WebformSame extends Checkbox {
protected function defineDefaultProperties() {
$properties = [
'source' => '',
'destination' => '',
'destination_state' => 'visible',
] + parent::defineDefaultProperties();
unset($properties['required'], $properties['required_error']);
return $properties;
}
public function form(array $form, FormStateInterface $form_state) {
$webform = $form_state
->getFormObject()
->getWebform();
$form = parent::form($form, $form_state);
$ignored_types = [
'webform_same',
];
$flattened_elements = $webform
->getElementsInitializedFlattenedAndHasValue();
$options = [];
foreach ($flattened_elements as $element_key => $element) {
$element_plugin = $this->elementManager
->getElementInstance($element);
if (!in_array($element_plugin
->getPluginId(), $ignored_types)) {
$options[(string) $element_plugin
->getPluginLabel()][$element_key] = $element['#admin_title'];
}
}
ksort($options);
$form['same'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Same as settings'),
'#destination' => $this
->t('Please note, the source and destination element must be the same element types.'),
];
$form['same']['source'] = [
'#type' => 'select',
'#title' => $this
->t('Source element'),
'#options' => $options,
'#required' => TRUE,
];
$form['same']['destination'] = [
'#type' => 'select',
'#title' => $this
->t('Destination element'),
'#options' => $options,
'#required' => TRUE,
];
$form['same']['destination_state'] = [
'#type' => 'select',
'#title' => $this
->t('Destination state'),
'#description' => $this
->t("Determine how the destination element's state is toggled when 'Same as' is checked"),
'#options' => [
'visible' => $this
->t('Show/hide'),
'visible-slide' => $this
->t('Slide in/out'),
],
'#required' => TRUE,
];
$form['same']['destination']['#element_validate'] = [
[
get_called_class(),
'validateDestination',
],
];
return $form;
}
public static function validateDestination(array &$element, FormStateInterface $form_state) {
$webform = $form_state
->getFormObject()
->getWebform();
$values = $form_state
->getValues();
$source = $values['properties']['source'];
$source_element = $webform
->getElement($source);
$destination = $values['properties']['destination'];
$destination_element = $webform
->getElement($destination);
if ($destination === $source) {
$form_state
->setError($element, t('The source and destination can not be the same element.'));
}
elseif ($destination_element['#type'] !== $source_element['#type']) {
$element_manager = \Drupal::service('plugin.manager.webform.element');
$element_plugin = $element_manager
->getElementInstance($element);
$t_args = [
'@type' => $element_plugin
->getPluginLabel(),
'@source' => $source_element['#admin_title'],
'@destination' => $destination_element['#admin_title'],
];
$form_state
->setError($element, t('The destination element (@destination) must be the same element type (@type) as source element (@source).', $t_args));
}
}
public function alterForm(array &$element, array &$form, FormStateInterface $form_state) {
if (!isset($element['#source']) || !isset($element['#destination'])) {
return;
}
$source = $element['#source'];
$source_element = WebformElementHelper::getElement($form, $source);
if (!$source_element) {
return;
}
$destination = $element['#destination'];
$destination_element =& WebformElementHelper::getElement($form, $destination);
if (!$destination_element) {
return;
}
$selector = ':input[name="' . $element['#webform_key'] . '"]';
$state = !empty($element['#destination_state']) ? $element['#destination_state'] : 'visible';
$destination_element['#states'][$state][$selector] = [
'checked' => FALSE,
];
$destination_element['#states_clear'] = FALSE;
$form += [
'#webform_same' => [],
];
$form['#webform_same'][$element['#webform_key']] = [
'source' => $source,
'destination' => $destination,
];
$form['#validate'][] = [
get_called_class(),
'validateForm',
];
}
public static function validateForm(&$form, FormStateInterface $form_state) {
foreach ($form['#webform_same'] as $element_key => $settings) {
if ($form_state
->getValue($element_key)) {
$form_state
->setValue($settings['destination'], $form_state
->getValue($settings['source']));
}
}
}
public function preSave(array &$element, WebformSubmissionInterface $webform_submission) {
$webform = $webform_submission
->getWebform();
$same = $webform_submission
->getElementData($element['#webform_key']);
if (!$same) {
return;
}
$source = $element['#source'];
$destination = $element['#destination'];
if (!$webform
->getElement($source) || !$webform
->getElement($destination)) {
return;
}
$source_data = $webform_submission
->getElementData($source);
$webform_submission
->setElementData($destination, $source_data);
}
public function preview() {
return [
'#type' => $this
->getTypeName(),
'#title' => $this
->t('Billing address is the same as the shipping address'),
];
}
}