diff --git a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php index 1319dc3d22999b7c4522a90a381d7f36bd611808..25222b7897600b0568bf01be511bee9f3cdec350 100644 --- a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php +++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php @@ -151,10 +151,9 @@ public static function validateUriElement($element, FormStateInterface $form_sta */ public static function validateTitleElement(&$element, FormStateInterface $form_state, $form) { if ($element['uri']['#value'] !== '' && $element['title']['#value'] === '') { - $element['title']['#required'] = TRUE; // We expect the field name placeholder value to be wrapped in t() here, // so it won't be escaped again as it's already marked safe. - $form_state->setError($element['title'], t('@name field is required.', ['@name' => $element['title']['#title']])); + $form_state->setError($element['title'], t('@title field is required if there is @uri input.', ['@title' => $element['title']['#title'], '@uri' => $element['uri']['#title']])); } } @@ -218,12 +217,29 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen '#default_value' => isset($items[$delta]->title) ? $items[$delta]->title : NULL, '#maxlength' => 255, '#access' => $this->getFieldSetting('title') != DRUPAL_DISABLED, + '#required' => $this->getFieldSetting('title') === DRUPAL_REQUIRED && $element['#required'], ]; // Post-process the title field to make it conditionally required if URL is // non-empty. Omit the validation on the field edit form, since the field // settings cannot be saved otherwise. - if (!$this->isDefaultValueWidget($form_state) && $this->getFieldSetting('title') == DRUPAL_REQUIRED) { + if (!$this->isDefaultValueWidget($form_state) && $this->getFieldSetting('title') === DRUPAL_REQUIRED) { $element['#element_validate'][] = [get_called_class(), 'validateTitleElement']; + + if (!$element['title']['#required']) { + // Make title required on the front-end when URI filled-in. + $field_name = $this->fieldDefinition->get('field_name'); + + $parents = $element['#field_parents']; + $parents[] = $field_name; + $selector = $root = array_shift($parents); + if ($parents) { + $selector = $root . '[' . implode('][', $parents) . ']'; + } + + $element['title']['#states']['required'] = [ + ':input[name="' . $selector . '[' . $delta . '][uri]"]' => ['filled' => TRUE] + ]; + } } // Exposing the attributes array in the widget is left for alternate and more diff --git a/core/modules/link/tests/src/Functional/LinkFieldTest.php b/core/modules/link/tests/src/Functional/LinkFieldTest.php index c99ad0a931060dd097df970092a13408ec647239..065a2bddec5e395f7fd3f4ae5cf157fdba6f1eee 100644 --- a/core/modules/link/tests/src/Functional/LinkFieldTest.php +++ b/core/modules/link/tests/src/Functional/LinkFieldTest.php @@ -282,7 +282,7 @@ public function testLinkTitle() { "{$field_name}[0][uri]" => 'http://www.example.com', ]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText(t('@name field is required.', ['@name' => t('Link text')])); + $this->assertText(t('@title field is required if there is @uri input.', ['@title' => t('Link text'), '@uri' => t('URL')])); // Verify that the link text is not required, if the URL is empty. $edit = [