public function WebformSubmissionConditionsValidator::buildForm in Webform 8.5
Same name and namespace in other branches
- 6.x src/WebformSubmissionConditionsValidator.php \Drupal\webform\WebformSubmissionConditionsValidator::buildForm()
Apply form #states to visible elements.
Parameters
array $form: An associative array containing the structure of the form.
\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.
Overrides WebformSubmissionConditionsValidatorInterface::buildForm
See also
\Drupal\webform\WebformSubmissionForm::buildForm
File
- src/
WebformSubmissionConditionsValidator.php, line 96
Class
- WebformSubmissionConditionsValidator
- Webform submission conditions (#states) validator.
Namespace
Drupal\webformCode
public function buildForm(array &$form, FormStateInterface $form_state) {
/** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
$webform_submission = $form_state
->getFormObject()
->getEntity();
// Get build/visible form elements.
$visible_elements =& $this
->getBuildElements($form);
// Loop through visible elements with #states.
foreach ($visible_elements as &$element) {
$states =& WebformElementHelper::getStates($element);
// Store original #states in #_webform_states.
$element['#_webform_states'] = $states;
foreach ($states as $original_state => $conditions) {
if (!is_array($conditions)) {
continue;
}
// Process state/negate.
list($state, $negate) = $this
->processState($original_state);
// If hide/show we need to make sure that validation is not triggered.
if (strpos($state, 'visible') === 0) {
$element['#after_build'][] = [
get_class($this),
'elementAfterBuild',
];
}
$targets = $this
->getConditionTargetsVisibility($conditions, $visible_elements);
// Determine if targets are visible or cross page.
$all_targets_visible = array_sum($targets) === count($targets);
$has_cross_page_targets = !$all_targets_visible && array_sum($targets);
// Skip if evaluating conditions when all targets are visible.
if ($all_targets_visible) {
// Add .js-webform-states-hidden to element's that are not visible when
// the form is rendered.
if (strpos($state, 'visible') === 0 && !$this
->validateConditions($conditions, $webform_submission)) {
$this
->addStatesHiddenToElement($element);
}
continue;
}
// Replace hidden cross page targets with hidden inputs.
if ($has_cross_page_targets) {
$cross_page_targets = array_filter($targets, function ($visible) {
return $visible === FALSE;
});
$states[$original_state] = $this
->replaceCrossPageTargets($conditions, $webform_submission, $cross_page_targets, $form);
continue;
}
$result = $this
->validateConditions($conditions, $webform_submission);
// Skip invalid conditions.
if ($result === NULL) {
continue;
}
// Negate the result.
$result = $negate ? !$result : $result;
// Apply result to element state.
switch ($state) {
case 'required':
$element['#required'] = $result;
break;
case 'readonly':
// Set custom readonly attribute and class.
// We can't use the custom #readonly property because it is
// processed before cross page targets.
// @see \Drupal\webform\Plugin\WebformElementBase::prepare
if ($result) {
$element['#attributes']['readonly'] = 'readonly';
$element['#wrapper_attributes']['class'][] = 'webform-readonly';
}
break;
case 'disabled':
$element['#disabled'] = $result;
break;
case 'visible':
case 'visible-slide':
if (!$result) {
// Visual hide the element.
$this
->addStatesHiddenToElement($element);
// Clear the default value.
if (!isset($element['#states_clear']) || $element['#states_clear'] === TRUE) {
unset($element['#default_value']);
}
}
break;
case 'collapsed':
$element['#open'] = !$result;
break;
case 'checked':
$element['#default_value'] = $result;
break;
}
// Remove #states state/conditions.
unset($states[$original_state]);
}
// Remove #states if all states have been applied.
if (empty($states)) {
unset($element['#states']);
}
}
}