Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andybroomfield/ef5d7e92e19e8642c40ab170f51212a7 to your computer and use it in GitHub Desktop.
Save andybroomfield/ef5d7e92e19e8642c40ab170f51212a7 to your computer and use it in GitHub Desktop.
/**
* Determine if an element is visible by checking visiblity of parents.
*
* A helper around
* \Drupal::service('webform_submission.conditions_validator')->isElementVisible
* @param Array $element
* Webform element.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Form state object.
* @param Array $complete_form
* Form array.
* @return boolean
* True if all parent elements and the element itself if visible,
* else FALSE.
*/
public static function isElementVisibleThroughParent($element, FormStateInterface $form_state, &$complete_form) {
// Build webform submission and get conditions validator service.
$form_object = $form_state->getFormObject();
$webform_submission = $form_object->buildEntity($complete_form, $form_state);
$conditions_validator = \Drupal::service('webform_submission.conditions_validator');
// Loop through each of parents elements to work out visibility.
$parents = $element['#webform_parents'];
$parent_container = $complete_form['elements'];
foreach ($parents as $parent) {
$parent_container = $parent_container[$parent];
$is_visible = $conditions_validator->isElementVisible($parent_container, $webform_submission);
// Return FALSE as soon as an invisible element is found.
// The element itself will be invisible if its parent is.
if (!$is_visible) {
return FALSE;
}
}
// If all parents are visible, then return visibility of the element itself.
return $conditions_validator->isElementVisible($element, $webform_submission);
}
/**
* {@inheritdoc}
*/
public static function validateWebformComposite(&$element, FormStateInterface $form_state, &$complete_form) {
// IMPORTANT: Must get values from the $form_states since sub-elements
// may call $form_state->setValueForElement() via their validation hook.
// @see \Drupal\webform\Element\WebformEmailConfirm::validateWebformEmailConfirm
// @see \Drupal\webform\Element\WebformOtherBase::validateWebformOther
$value = NestedArray::getValue($form_state->getValues(), $element['#parents']);
$element_key = end($element['#parents']);
// If the element or any of its parent containers are hidden by conditions,
// Bypass validation and clear any required element errors generated
// for this element.
if (!self::isElementVisibleThroughParent($element, $form_state, $complete_form)) {
$form_errors = $form_state->getErrors();
$form_state->clearErrors();
foreach($form_errors as $error_key => $error_value) {
if (strpos($error_key, $element_key . ']') !== 0) {
$form_state->setErrorByName($error_key, $error_value);
}
}
return;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment