diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index d8f3136..9082884 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -507,8 +507,8 @@ function template_preprocess_datetime_wrapper(&$variables) {
}
$variables['required'] = FALSE;
- // For required datetime fields a 'form-required' class is appended to the
- // label attributes.
+ // For required datetime fields 'form-required' & 'js-form-required' classes
+ // are appended to the label attributes.
if (!empty($element['#required'])) {
$variables['required'] = TRUE;
}
@@ -1606,6 +1606,7 @@ function template_preprocess_field_multiple_value_form(&$variables) {
$order_class = $element['#field_name'] . '-delta-order';
$header_attributes = new Attribute(array('class' => array('label')));
if (!empty($element['#required'])) {
+ $header_attributes['class'][] = 'js-form-required';
$header_attributes['class'][] = 'form-required';
}
$header = array(
diff --git a/core/misc/states.js b/core/misc/states.js
index b969da7..1c9e5e6 100644
--- a/core/misc/states.js
+++ b/core/misc/states.js
@@ -526,12 +526,12 @@
if (e.value) {
var $label = $(e.target).attr({'required': 'required', 'aria-required': 'aria-required'}).closest('.form-item, .form-wrapper').find('label');
// Avoids duplicate required markers on initialization.
- if (!$label.hasClass('form-required').length) {
- $label.addClass('form-required');
+ if (!$label.hasClass('js-form-required').length) {
+ $label.addClass('js-form-required form-required');
}
}
else {
- $(e.target).removeAttr('required aria-required').closest('.form-item, .form-wrapper').find('label.form-required').removeClass('form-required');
+ $(e.target).removeAttr('required aria-required').closest('.form-item, .form-wrapper').find('label.js-form-required').removeClass('js-form-required form-required');
}
}
});
diff --git a/core/modules/datetime/src/Tests/DateTimeFieldTest.php b/core/modules/datetime/src/Tests/DateTimeFieldTest.php
index f3fcae1..d07a244 100644
--- a/core/modules/datetime/src/Tests/DateTimeFieldTest.php
+++ b/core/modules/datetime/src/Tests/DateTimeFieldTest.php
@@ -100,7 +100,7 @@ function testDateField() {
// Display creation form.
$this->drupalGet('entity_test/add');
$this->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.');
- $this->assertFieldByXPath('//*[@id="edit-' . $field_name . '-wrapper"]/h4[contains(@class, "form-required")]', TRUE, 'Required markup found');
+ $this->assertFieldByXPath('//*[@id="edit-' . $field_name . '-wrapper"]/h4[contains(@class, "js-form-required")]', TRUE, 'Required markup found');
$this->assertNoFieldByName("{$field_name}[0][value][time]", '', 'Time element not found.');
// Submit a valid date and ensure it is accepted.
diff --git a/core/modules/field/src/Tests/FormTest.php b/core/modules/field/src/Tests/FormTest.php
index 748d2ac..4b21bc4 100644
--- a/core/modules/field/src/Tests/FormTest.php
+++ b/core/modules/field/src/Tests/FormTest.php
@@ -334,12 +334,12 @@ public function testFieldFormUnlimitedRequired() {
// Display creation form -> 1 widget.
$this->drupalGet('entity_test/add');
// Check that the Required symbol is present for the multifield label.
- $this->assertRaw(SafeMarkup::format('
@label
', array('@label' => $this->field['label'])),
- 'Required symbol added field label.');
+ $element = $this->xpath('//h4[contains(@class, "label") and contains(@class, "js-form-required") and contains(text(), :value)]', array(':value' => $this->field['label']));
+ $this->assertTrue(isset($element[0]), 'Required symbol added field label.');
// Check that the label of the field input is visually hidden and contains
// the field title and an indication of the delta for a11y.
- $this->assertRaw(SafeMarkup::format('', array('@label' => $this->field['label'])),
- 'Required symbol not added for field input.');
+ $element = $this->xpath('//label[@for=:for and contains(@class, "js-form-required") and contains(text(), :value)]', array(':for' => 'edit-field-unlimited-0-value', ':value' => $this->field['label'] . ' (value 1)'));
+ $this->assertTrue(isset($element[0]), 'Required symbol not added for field input.');
}
/**
diff --git a/core/modules/field_ui/field_ui.js b/core/modules/field_ui/field_ui.js
index 9bdbe50..0056904 100644
--- a/core/modules/field_ui/field_ui.js
+++ b/core/modules/field_ui/field_ui.js
@@ -11,15 +11,16 @@
attach: function (context) {
var $form = $(context).find('#field-ui-field-storage-add-form').once('field_ui_add');
if ($form.length) {
- // Add a few 'form-required' css classes here. We can not use the Form API
- // '#required' property because both label elements for "add new" and
- // "re-use existing" can never be filled and submitted at the same time.
+ // Add a few 'js-form-required' and 'form-required' CSS classes here. We
+ // can not use the Form API '#required' property because both label
+ // elements for "add new" and "re-use existing" can never be filled and
+ // submitted at the same time.
// The actual validation will happen server-side.
$form.find(
'.form-item-label label,' +
'.form-item-field-name label,' +
'.form-item-existing-storage-label label')
- .addClass('form-required');
+ .addClass('js-form-required form-required');
var $newFieldType = $form.find('select[name="new_storage_type"]');
var $existingStorageName = $form.find('select[name="existing_storage_name"]');
diff --git a/core/modules/image/src/Tests/ImageFieldValidateTest.php b/core/modules/image/src/Tests/ImageFieldValidateTest.php
index 938176a..ee76462 100644
--- a/core/modules/image/src/Tests/ImageFieldValidateTest.php
+++ b/core/modules/image/src/Tests/ImageFieldValidateTest.php
@@ -69,11 +69,11 @@ function testRequiredAttributes() {
$this->uploadNodeImage($image, $field_name, 'article');
// Look for form-required for the alt text.
- $elements = $this->xpath('//label[@for="edit-' . $field_name . '-0-alt" and @class="form-required"]/following-sibling::input[@id="edit-' . $field_name . '-0-alt"]');
+ $elements = $this->xpath('//label[@for="edit-' . $field_name . '-0-alt" and @class="js-form-required form-required"]/following-sibling::input[@id="edit-' . $field_name . '-0-alt"]');
$this->assertTrue(isset($elements[0]),'Required marker is shown for the required alt text.');
- $elements = $this->xpath('//label[@for="edit-' . $field_name . '-0-title" and @class="form-required"]/following-sibling::input[@id="edit-' . $field_name . '-0-title"]');
+ $elements = $this->xpath('//label[@for="edit-' . $field_name . '-0-title" and @class="js-form-required form-required"]/following-sibling::input[@id="edit-' . $field_name . '-0-title"]');
$this->assertTrue(isset($elements[0]), 'Required marker is shown for the required title text.');
diff --git a/core/modules/system/src/Tests/Form/ElementsLabelsTest.php b/core/modules/system/src/Tests/Form/ElementsLabelsTest.php
index db5dbee..cc3ce30 100644
--- a/core/modules/system/src/Tests/Form/ElementsLabelsTest.php
+++ b/core/modules/system/src/Tests/Form/ElementsLabelsTest.php
@@ -53,16 +53,16 @@ function testFormLabels() {
// Exercise various defaults for textboxes and modifications to ensure
// appropriate override and correct behavior.
- $elements = $this->xpath('//label[@for="edit-form-textfield-test-title-and-required" and @class="form-required"]/following-sibling::input[@id="edit-form-textfield-test-title-and-required"]');
+ $elements = $this->xpath('//label[@for="edit-form-textfield-test-title-and-required" and @class="js-form-required form-required"]/following-sibling::input[@id="edit-form-textfield-test-title-and-required"]');
$this->assertTrue(isset($elements[0]), 'Label precedes textfield, with required marker inside label.');
- $elements = $this->xpath('//input[@id="edit-form-textfield-test-no-title-required"]/preceding-sibling::label[@for="edit-form-textfield-test-no-title-required" and @class="form-required"]');
+ $elements = $this->xpath('//input[@id="edit-form-textfield-test-no-title-required"]/preceding-sibling::label[@for="edit-form-textfield-test-no-title-required" and @class="js-form-required form-required"]');
$this->assertTrue(isset($elements[0]), 'Label tag with required marker precedes required textfield with no title.');
$elements = $this->xpath('//input[@id="edit-form-textfield-test-title-invisible"]/preceding-sibling::label[@for="edit-form-textfield-test-title-invisible" and @class="visually-hidden"]');
$this->assertTrue(isset($elements[0]), 'Label preceding field and label class is visually-hidden.');
- $elements = $this->xpath('//input[@id="edit-form-textfield-test-title"]/preceding-sibling::span[@class="form-required"]');
+ $elements = $this->xpath('//input[@id="edit-form-textfield-test-title"]/preceding-sibling::span[@class="js-form-required form-required"]');
$this->assertFalse(isset($elements[0]), 'No required marker on non-required field.');
$elements = $this->xpath('//input[@id="edit-form-textfield-test-title-after"]/following-sibling::label[@for="edit-form-textfield-test-title-after" and @class="option"]');
diff --git a/core/modules/system/src/Tests/Form/FormTest.php b/core/modules/system/src/Tests/Form/FormTest.php
index 321502d..0bca2cb 100644
--- a/core/modules/system/src/Tests/Form/FormTest.php
+++ b/core/modules/system/src/Tests/Form/FormTest.php
@@ -97,7 +97,7 @@ function testRequiredFields() {
$elements['file']['empty_values'] = $empty_strings;
// Regular expression to find the expected marker on required elements.
- $required_marker_preg = '@<.*?class=".*?form-required.*?">@';
+ $required_marker_preg = '@<.*?class=".*?js-form-required.*form-required.*?">@';
// Go through all the elements and all the empty values for them.
foreach ($elements as $type => $data) {
foreach ($data['empty_values'] as $key => $empty) {
diff --git a/core/modules/system/templates/datetime-wrapper.html.twig b/core/modules/system/templates/datetime-wrapper.html.twig
index 443b5b3..62a4b9d 100644
--- a/core/modules/system/templates/datetime-wrapper.html.twig
+++ b/core/modules/system/templates/datetime-wrapper.html.twig
@@ -17,7 +17,7 @@
#}
{%
set title_classes = [
- required ? 'form-required',
+ required ? 'js-form-required',
]
%}
{% if title %}
diff --git a/core/modules/system/templates/fieldset.html.twig b/core/modules/system/templates/fieldset.html.twig
index ab6796c..f7af6fa 100644
--- a/core/modules/system/templates/fieldset.html.twig
+++ b/core/modules/system/templates/fieldset.html.twig
@@ -25,7 +25,7 @@
{%
set legend_span_classes = [
'fieldset-legend',
- required ? 'form-required',
+ required ? 'js-form-required',
]
%}
{# Always wrap fieldset legends in a SPAN for CSS positioning. #}
diff --git a/core/modules/system/templates/form-element-label.html.twig b/core/modules/system/templates/form-element-label.html.twig
index 6ececd9..644b4bd 100644
--- a/core/modules/system/templates/form-element-label.html.twig
+++ b/core/modules/system/templates/form-element-label.html.twig
@@ -18,7 +18,7 @@
set classes = [
title_display == 'after' ? 'option',
title_display == 'invisible' ? 'visually-hidden',
- required ? 'form-required',
+ required ? 'js-form-required',
]
%}
{% if title is not empty or required -%}
diff --git a/core/themes/classy/templates/form/datetime-wrapper.html.twig b/core/themes/classy/templates/form/datetime-wrapper.html.twig
index 399dea2..e3f504b 100644
--- a/core/themes/classy/templates/form/datetime-wrapper.html.twig
+++ b/core/themes/classy/templates/form/datetime-wrapper.html.twig
@@ -16,6 +16,7 @@
{%
set title_classes = [
'label',
+ required ? 'js-form-required',
required ? 'form-required',
]
%}
diff --git a/core/themes/classy/templates/form/fieldset.html.twig b/core/themes/classy/templates/form/fieldset.html.twig
index f7460cf..7eb65f9 100644
--- a/core/themes/classy/templates/form/fieldset.html.twig
+++ b/core/themes/classy/templates/form/fieldset.html.twig
@@ -23,6 +23,7 @@
{%
set legend_span_classes = [
'fieldset-legend',
+ required ? 'js-form-required',
required ? 'form-required',
]
%}
diff --git a/core/themes/classy/templates/form/form-element-label.html.twig b/core/themes/classy/templates/form/form-element-label.html.twig
index 70ed96c..7c2f8f2 100644
--- a/core/themes/classy/templates/form/form-element-label.html.twig
+++ b/core/themes/classy/templates/form/form-element-label.html.twig
@@ -16,6 +16,7 @@
set classes = [
title_display == 'after' ? 'option',
title_display == 'invisible' ? 'visually-hidden',
+ required ? 'js-form-required',
required ? 'form-required',
]
%}