diff --git a/core/lib/Drupal/Core/Render/Element/MachineName.php b/core/lib/Drupal/Core/Render/Element/MachineName.php index 6e3ccb6b32..9aa053efe4 100644 --- a/core/lib/Drupal/Core/Render/Element/MachineName.php +++ b/core/lib/Drupal/Core/Render/Element/MachineName.php @@ -150,6 +150,17 @@ public static function processMachineName(&$element, FormStateInterface $form_st 'field_suffix' => $element['#field_suffix'], ]; + // Store the initial value in form state. The machine name needs this to + // ensure that the exists function is not called for existing values when + // editing them. + $initial_values = $form_state->get('machine_name.initial_values') ?: []; + // Store the initial values in an array so we can differentiate between a + // NULL default value and a new machine name element. + if (!array_key_exists($element['#id'], $initial_values)) { + $initial_values[$element['#id']] = $element['#default_value']; + $form_state->set('machine_name.initial_values', $initial_values); + } + // By default, machine names are restricted to Latin alphanumeric characters. // So, default to LTR directionality. if (!isset($element['#attributes'])) { @@ -246,15 +257,13 @@ public static function validateMachineName(&$element, FormStateInterface $form_s } } - // Verify that the machine name is unique. Check form state if we need to - // explicitly validate the element. This happens every time when an error - // has been set, since this breaks on AJAX requests - $needs_revalidating = $form_state->get('machine_name.needs_revalidating') ?: []; - if ($element['#default_value'] !== $element['#value'] || isset($needs_revalidating[$element['#name']])) { + // Verify that the machine name is unique. If the value matches the initial + // default value then it does not need to be validated as the machine name + // elements assumes the form is editing the existing value. + $initial_values = $form_state->get('machine_name.initial_values') ?: []; + if (!array_key_exists($element['#id'], $initial_values) || $initial_values[$element['#id']] !== $element['#value']) { $function = $element['#machine_name']['exists']; if (call_user_func($function, $element['#value'], $element, $form_state)) { - $needs_revalidating[$element['#name']] = TRUE; - $form_state->set('machine_name.needs_revalidating', $needs_revalidating); $form_state->setError($element, t('The machine-readable name is already in use. It must be unique.')); } }