diff -u b/core/lib/Drupal/Core/Entity/Field/Field.php b/core/lib/Drupal/Core/Entity/Field/Field.php --- b/core/lib/Drupal/Core/Entity/Field/Field.php +++ b/core/lib/Drupal/Core/Entity/Field/Field.php @@ -247,13 +247,20 @@ /** * {@inheritdoc} */ + public function isRequired() { + return $this->getFieldDefinition()->isFieldRequired(); + } + + /** + * {@inheritdoc} + */ public function getConstraints() { // Constraints usually apply to the field item, but required does make // sense on the field only. So we special-case it to apply to the field for // now. - // @todo: Separate list and list item definitions to separate constraints. + // @todo Separate list and list item definitions to separate constraints. $constraints = array(); - if ($this->getFieldDefinition()->isFieldRequired()) { + if ($this->isRequired()) { $constraints[] = \Drupal::typedData()->getValidationConstraintManager()->create('NotNull', array()); } return $constraints; diff -u b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php --- b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php @@ -66,6 +66,14 @@ /** * {@inheritdoc} */ + public function isRequired() { + // Adding a default value is not required even if the field is otherwise. + return empty($this->getParent()->field_ui_default_value) && parent::isRequired(); + } + + /** + * {@inheritdoc} + */ public function getConstraints() { $constraints = parent::getConstraints(); // Check that the number of values doesn't exceed the field cardinality. For diff -u b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php --- b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php @@ -212,7 +212,7 @@ '#theme' => 'field_multiple_value_form', '#field_name' => $field_name, '#cardinality' => $cardinality, - '#required' => $this->fieldDefinition->isFieldRequired(), + '#required' => $items->isRequired(), '#title' => $title, '#description' => $description, '#prefix' => '
', @@ -253,7 +253,7 @@ '#language' => $langcode, '#field_parents' => $form['#parents'], // Only the first widget should be required. - '#required' => $delta == 0 && $this->fieldDefinition->isFieldRequired(), + '#required' => $delta == 0 && $items->isRequired(), '#delta' => $delta, '#weight' => $delta, ); @@ -335,6 +335,15 @@ * {@inheritdoc} */ public function flagErrors(EntityInterface $entity, $langcode, FieldInterface $items, array $form, array &$form_state) { + // If element-level validation already reported errors, we can skip + // reporting more. + // @todo Despite the above, we shouldn't need to do this. We do it only + // because the rest of this function causes some test failures. Remove + // this when it's fixed. + if (form_get_errors()) { + return; + } + $field_name = $this->fieldDefinition->getFieldName(); $field_state = field_form_get_state($form['#parents'], $field_name, $langcode, $form_state); diff -u b/core/modules/node/lib/Drupal/node/Plugin/field/widget/TitleWidget.php b/core/modules/node/lib/Drupal/node/Plugin/field/widget/TitleWidget.php --- b/core/modules/node/lib/Drupal/node/Plugin/field/widget/TitleWidget.php +++ b/core/modules/node/lib/Drupal/node/Plugin/field/widget/TitleWidget.php @@ -48,7 +48,7 @@ $addition[$field_name] = array( '#type' => 'textfield', '#title' => check_plain($label), - '#required' => $this->fieldDefinition->isFieldRequired(), + '#required' => $items->isRequired(), '#default_value' => isset($items[0]->value) ? $items[0]->value : '', '#maxlength' => $this->fieldDefinition->getFieldSetting('max_length'), ); diff -u b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php --- b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php @@ -55,13 +55,13 @@ $violations = $node->validate(); $this->assertEqual(count($violations), 1, 'Violation found when title is too long.'); $this->assertEqual($violations[0]->getPropertyPath(), 'title.0.value'); - $this->assertEqual($violations[0]->getMessage(), t('Title: the text may not be longer than 255 characters.', array('%limit' => 255))); + $this->assertEqual($violations[0]->getMessage(), 'Title: the text may not be longer than 255 characters.'); $node->set('title', NULL); $violations = $node->validate(); $this->assertEqual(count($violations), 1, 'Violation found when title is not set.'); $this->assertEqual($violations[0]->getPropertyPath(), 'title'); - $this->assertEqual($violations[0]->getMessage(), t('This value should not be null.')); + $this->assertEqual($violations[0]->getMessage(), 'This value should not be null.'); // Make the title valid again. $node->set('title', $this->randomString()); @@ -73,5 +73,5 @@ $this->assertEqual(count($violations), 1, 'Violation found when changed date is before the last changed date.'); $this->assertEqual($violations[0]->getPropertyPath(), 'changed.0.value'); - $this->assertEqual($violations[0]->getMessage(), t('The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.')); + $this->assertEqual($violations[0]->getMessage(), 'The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.'); } } only in patch2: unchanged: --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -4837,7 +4837,7 @@ function _form_set_attributes(&$element, $class = array()) { // form_builder(). if (!empty($element['#required'])) { $element['#attributes']['class'][] = 'required'; - $element['#attributes']['required'] = 'required'; + //$element['#attributes']['required'] = 'required'; $element['#attributes']['aria-required'] = 'true'; } if (isset($element['#parents']) && form_get_error($element) !== NULL && !empty($element['#validated'])) { only in patch2: unchanged: --- a/core/lib/Drupal/Core/Entity/Field/FieldInterface.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldInterface.php @@ -130,4 +130,12 @@ public function delete(); */ public function deleteRevision(); + /** + * Returns TRUE if the field is required. + * + * @return bool + * TRUE if the field is required. + */ + public function isRequired(); + }