Problem/Motivation

The textfield input for "user field" is #required, but has no label (the label is held by the table header) and thus shouldn't have a lone red asterisk. Seven correctly omits the marker if the label is empty.
Example of a form 'multiple, required' field form Bartik :

user_registration_form.png

Seen in #501408: Display user fields on registration form, but is also visible in current HEAD when editing an existing user account with fields.

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue category Bug because the information of the field being required should not appear twice
Issue priority Major because tim.plunkett said so ;)
Unfrozen changes Unfrozen because it only changes markup on fields widget that are set as required and allowing multiple values.
Prioritized changes The main goal of this issue is usability and accessibility. Usability by hiding a non-pertinent mark near the input field. Accessibility by providing a valuable label for the multiple input fields.
Disruption This change could be disruptive for themes because it forces some form labels to be hidden.

Proposed resolution

For these cases mark the title_display as hidden:
'#title_display' => 'invisible',

Remaining tasks

Contributor tasks needed
Task Novice task? Contributor instructions Complete?
Create a patch Instructions Done
Reroll the patch if it no longer applies. Novice Instructions Done
Update the issue summary Instructions Done
Update the issue summary noting if allowed during the beta Instructions Done
Add automated tests Instructions Done
Manually test the patch Novice Instructions Done
Embed before and after screenshots in the issue summary Novice Instructions Done
Review patch to ensure that it fixes the issue, stays within scope, is properly documented, and follows coding standards Instructions

User interface changes

Yes, the red asterisk moves to the correct location AND accessibility is enhanced by a better label around the fields.

Before :

<h4 class="label form-required">My unlimited required field label</h4>
[...]
<label for="edit-field-unlimited-0-value" class="form-required"></label>

After :

<h4 class="label form-required">My unlimited required field label</h4>
[...]
<label for="edit-field-unlimited-0-value" class="visually-hidden form-required">My unlimited required field label (value 1)</label>

API changes

n/a

CommentFileSizeAuthor
#145 980144-multiple-text_with_summary-7.82.png11.29 KBcodebymikey
#145 980144-multiple-text_with_summary-7.80.png12.38 KBcodebymikey
#114 980144-114.patch2.98 KBaerozeppelin
#114 interdiff-980144-98-114.txt595 bytesaerozeppelin
#103 980144-screenshot-103.png6.63 KBdxvargas
#102 Screen Shot 2017-01-03 at 3.24.58 PM.png31.1 KBmgifford
#98 980144-98.patch3.01 KBaerozeppelin
#98 interdiff-980144-96-98.txt1.86 KBaerozeppelin
#96 980144-96.patch2.89 KBaerozeppelin
#96 interdiff-980144-77-96.txt2.37 KBaerozeppelin
#87 Multiple-Required-Post-Patch.png79.22 KBmgifford
#87 Multiple-Required-Pre-Patch.png76.41 KBmgifford
#77 d7-issues_with_required-980144-76.patch3.01 KBDuaelFr
#76 d7-issues_with_required-980144-76-tests-only.patch1.67 KBDuaelFr
#76 d7-issues_with_required-980144-76-tests-only.patch1.67 KBDuaelFr
#72 interdiff.980144.70.72.txt667 bytesDuaelFr
#72 issues_with_required-980144-72.patch3.52 KBDuaelFr
#70 issues_with_required-980144-70.patch3.52 KBDuaelFr
#68 interdiff.980144.66.68.txt2.49 KBDuaelFr
#68 issues_with_required-980144-68.patch44.53 KBDuaelFr
#66 interdiff.980144.58.66.txt1.04 KBDuaelFr
#66 issues_with_required-980144-66.patch3.01 KBDuaelFr
#58 d8_multiple_required_field_after.png7.46 KBDuaelFr
#58 d8_multiple_required_field_before.png7.74 KBDuaelFr
#58 interdiff.980144.55.58.txt2.35 KBDuaelFr
#58 issues_with_required-980144-58.patch2.77 KBDuaelFr
#55 issues_with_required-980144-55.patch2.72 KBDuaelFr
#52 field-980144-52.patch2.77 KBswentel
#51 field-980144-51-D7-do-not-test.patch1.33 KBasgorobets
#47 field-980144-47.patch2.92 KBACF
#47 field-980144-test.patch1.79 KBACF
#46 field-980144-46.patch2.75 KBACF
#46 field-980144-test.patch1.62 KBACF
#45 field-980144-45-D7-do-not-test.patch1.33 KBtim.plunkett
#44 field-980144-44.patch1.13 KBtim.plunkett
#35 drupal_core-8.x-fix_multivalue_validation-980144-35b.patch1.26 KBmgifford
#33 D8-errors.png41.59 KBmgifford
#32 drupal_core-8.x-fix_multivalue_validation-980144-32.patch1.55 KBDuaelFr
#31 dp_multiple_fields_missing_title.png16.36 KBDuaelFr
#30 drupal_core-fix_multivalue_validation-980144-30.patch1.3 KBpoedan
#29 drupal_core-fix_multivalue_validation-980144-29.patch1.3 KBpoedan
#24 fix_multivalue_validation.patch1.59 KBpoedan
#20 multiple-required-field.patch1.54 KBSamH
#14 form_required_empty_label-980144-14.patch1.41 KByched
#11 form_required_empty_label-980144-9.patch851 bytesyched
#12 form_required_empty_label-980144-10.patch851 bytesyched
#5 form_required_empty_label-980144-2.patch604 bytesyched
#4 multiple_required_field.png3.68 KByched
#2 form_required_empty_label-980144-2.patch1.54 KByched
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

yched’s picture

Component: Bartik theme » field system

Oop. Sorry for blaming Bartik. This happens in Seven as well.
I'm a bit perplexed not having noticed this earlier.

I need to check how we handled that in CCK D6.

yched’s picture

Component: field system » forms system
Status: Active » Needs review
FileSize
1.54 KB

Tracked this down to #558928: Form element labeling is inconsistent, inflexible and bad for accessibility, more specifically patch in #148, committed in #150 (there was a followup in the same thread).

In D6, theme_form_element() does (roughly) :

  if (!empty($element['#title'])) {
    $output .= ' <label (...) >. t('$title: $required');
  }

In D7, theme_form_element() does :

  // If #title is not set, we don't display any label or required marker.
  if (!isset($element['#title'])) {
    $element['#title_display'] = 'none';
  }
  // ...
  if ($element['#title_display'] != 'none') {
    $output .= theme('form_element_label', $variables);
  }

Attached patch reverts to

  if (!isset($element['#title']) || $element['#title'] === '') {
    $element['#title_display'] = 'none';
  }

(since '0' can be a valid label)

Note that Field API cannot set $element['#title_display'] = 'none' itself, because the $element is generated by the widget, in a way Field API does not control. All it can do is provide the title string the widget should use, setting it to empty when the field is displayed in a 'multiple field' table.

yched’s picture

yched’s picture

FileSize
3.68 KB

Oops, the OP was supposed to include a screenshot of the bug :
The required marker is taken care of in the table header, along with the label. The form element has no label and shouldn't have the marker either.

multiple_required_field.png

yched’s picture

I'm tired. Patch with git --no-prefix.

mgifford’s picture

Issue tags: +FAPI

Wow, took one year less a week for us to stumble across this bug. I'll look at this patch shortly. It is interesting looking at the process of actually registering users in live sites in D7. It is a piece which probably is far enough into the process that it's easy to miss.

How do we make sure that changes like this are caught earlier for D8?

Thanks @yched!

Status: Needs review » Needs work

The last submitted patch, form_required_empty_label-980144-2.patch, failed testing.

sun’s picture

Issue tags: -FAPI
+++ includes/form.inc
@@ -3759,7 +3759,7 @@ function theme_form_element($variables) {
   // If #title is not set, we don't display any label or required marker.

Comment needs to be updated and should elaborate a bit on the reasoning for the empty string check.

That said, assigning a #title but setting it to an empty string, sounds like a bogus idea to me in the first place.

Powered by Dreditor.

mgifford’s picture

@sun is there anything other than this comment that you'd change in the patch? Other than getting it through the simpletests?

It certainly seems to be an important issue to bring into core.

sun’s picture

I'm not sure whether we shouldn't fix Field module instead. Specifying an empty string as #title is perfectly valid from a Form API perspective, and getting an empty title potentially followed by a required marker is what I'd expect when doing that.

yched’s picture

Title: Issues with "required, multiple" fields in forms » Lone 'required' marker on required form fields with no label
Component: field system » forms system
FileSize
851 bytes

[crosspost with sun]

Fixing the test showed that the current behavior of outputting a lone required marker when #title == '' is currently explicitly tested and thus appears like an intentional feature. I can't pretend it's just an oversight.
D6 did not work that way, though (in D6 empty #title means no <label> and no 'required' marker').

@mgifford : you rolled a large number of the patches in #558928: Form element labeling is inconsistent, inflexible and bad for accessibility - you remember a specific rationale for this change ?

However, different approach : when the label display is taken care of somewhere else, Field API can set $element['#title_display'] = 'invisible'. This lets screen readers get a meaningful 'required' mark next to the input. While we're in there, this also lets us add a real title (including delta) for screen readers users, which currently have little way to tell where exactly where they are. This introduces a new translatable string, though --> 'string freeze' tag.

yched’s picture

Title: Lone 'required' marker on required form fields with no label » Issues with "required, multiple" fields in forms
Component: forms system » field system
Status: Needs work » Needs review
Issue tags: +String freeze
FileSize
851 bytes

Actually, this also fixes the issue that currently, "required, multiple" fields, having an empty #title, generate a dumb 'field is required' message (instead of the common, more accurate '[#title] field is required') on failed #required validation.

Thus, adjusting to a 'hidden title' more friendly for this context :
"@label (value @delta) field is required" reads better than
"@label - value @delta field is required"

In summary, the patch fixes several issues with "required, multiple" fields in forms :
- lone 'required marker' (see screenshot in #4)
- screen readers don't have any label for the input elements, and no way to differentiate the various deltas
- on failed '#required' validation, the error message doesn't point to a specific form field.

sun’s picture

Title: Lone 'required' marker on required form fields with no label » Issues with "required, multiple" fields in forms
Component: forms system » field system
+++ modules/field/field.form.inc
@@ -172,7 +172,8 @@ function field_multiple_value_form($field, $instance, $langcode, $items, &$form,
         // For multiple fields, title and description are handled by the wrapping table.
-        '#title' => $multiple ? '' : $title,
+        '#title' => $multiple ? t('@label (value @delta)', array('@label' => $title, '@delta' => $delta)) : $title,
+        '#title_display' => $multiple ? 'invisible' : 'before',
         '#description' => $multiple ? '' : $description,

We should move those conditional assignments into a real if/else condition. Like for #title, an empty #description should also output a totally needless empty DIV.description. Thus, a proper

if ($multiple) {
}
else {
}

separation would make much more sense here.

Not sure whether we need the @delta in the #title though. I think that aforementioned add-labels-for-accessibility patch contained similar constructs, so would be good to make this consistent.

Powered by Dreditor.

yched’s picture

Replaced ternaries with an if ($multiple).

re "an empty #description should also output a totally needless empty DIV.description"
It doesn't : I'm ready to bet that all your current fields are set up with an empty description, and you don't get that empty div, do you ? :-)

re "Not sure whether we need the @delta in the #title though"
Well, it does make sense for both screen readers and the failed validation message ?

mgifford’s picture

@yched - I was certainly very supportive of that patch. Like many patches, I've had to roll, re-roll, re-re-roll them to keep up with core and to bring in legitimate concerns from folks like @sun. I think at the end of the day I really don't like macro patches like this. It's just suich a difficult thing to test for.

I suspect that what happened is that the "required, multiple" use case just got overlooked. Considering that it took a year to find it, it's clear it's an edge use case. I don't know how many rare instances like this there are, but it would be good to document them so we know.

Looking back at the early patches it's clear that Everett's initial goal was to use attributes for inserting titles rather than invisible labels. Unfortunately in D7 we weren't able to bring attributes into the Forms API.

I think it was added in comment 140 after discussions with @chx and @sun. Owen & Brandon did most of the heavy lifting on this patch, and Owen's comments were "we can use #title being unset as an implicit 'none', which would work the same way in terms of output - suppressing the label completely - but would simplify the API a bit for most use cases. I am not sure which one I prefer - it doesn't seem too critical either way."

Seems we found a use case where it was critical. I would think that getting the Field API to display it as invisible would be preferred but can see if we can get some perspectives.

Everett Zufelt’s picture

I haven't read through all of the comments here. However, there is, IMO, no use-case for a null string to be used as a form field #title.

All fields need titles, whether they are displayed as a visible label, an invisible label or the @title attribute of the field itself.

The question is, are there times when the form field needs a visible required marker, and an invisible title. If there is really a use-case for this, then this is what needs to be addressed.

yched’s picture

there is, IMO, no use-case for a null string to be used as a form field #title. All fields need titles, whether they are displayed as a visible label, an invisible label or the @title attribute of the field itself
I probably agree - as the current approach for the patch shows. Screen readers need a usable label.

'Devil in the details' point about how to handle '#title' === '', though. D6 treats 'non-existent' and 'empty' #title similarly. D7 choses to threat 'empty' differently, and according to mgifford's #15, it is not entirely sure whether this was a conscious move.

Anyway - as far as this thread is concerned, this is a theoretical discussion. The way to fix the Field API issue at hand is to use #title_display wisely.

The question is, are there times when the form field needs a visible required marker, and an invisible title. If there is really a use-case for this, then this is what needs to be addressed.
This thread does not identify a use case for this :-)

Everett Zufelt’s picture

Issue tags: -String freeze

Status: Needs review » Needs work
Issue tags: +String freeze

The last submitted patch, form_required_empty_label-980144-14.patch, failed testing.

SamH’s picture

Status: Needs work » Needs review
FileSize
1.54 KB

Hi,

I ran into this problem as well. Tested the patch at #14 and it works on my local machine. I would change how @delta is added to #title, though. For me, the most common case of failed validation is when a user doesn't enter anything in the field. In this case, the only existing @delta is 0, and I think it can be removed without impacting screen readers.

So I would change

if ($multiple) {
        // Provide an accurate, hidden title for screen-readers and in case of
        // failed #required validation.
        $element['#title'] = t('@label (value @delta)', array('@label' => $title, '@delta' => $delta));
        $element['#title_display'] = 'invisible';
        $element['#description'] = '';
      }

to

      // For multiple fields, title and description are handled by the wrapping table.
      if ($multiple) {
        // Provide an accurate, hidden title for screen-readers and in case of
        // failed #required validation.
        if ($max == 0) {
          $element['#title'] = t('@label', array('@label' => $title));
        } else {
          $element['#title'] = t('@label (value @delta)', array('@label' => $title, '@delta' => $delta));
        }
        $element['#title_display'] = 'invisible';
        $element['#description'] = '';
      }

Is there anything I can do to help move this forward?

Status: Needs review » Needs work
Issue tags: -String freeze

The last submitted patch, multiple-required-field.patch, failed testing.

mgifford’s picture

Status: Needs work » Needs review

#20: multiple-required-field.patch queued for re-testing.

Status: Needs review » Needs work
Issue tags: +String freeze

The last submitted patch, multiple-required-field.patch, failed testing.

poedan’s picture

I have this problem as well. I also have the module media installed and the previous patches didn't work.
Here it is what is worked for me.

mgifford’s picture

Status: Needs work » Needs review

I think this might need to go to D8 and then get brought back to D7 but want the testing done now against D7.

Also setting to Needs review.

Status: Needs review » Needs work

The last submitted patch, fix_multivalue_validation.patch, failed testing.

skipyT’s picture

Status: Needs work » Needs review
skipyT’s picture

Status: Needs review » Needs work
poedan’s picture

poedan’s picture

Status: Needs work » Needs review
FileSize
1.3 KB

*Moved the status for needs review

DuaelFr’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
16.36 KB

Applies well on 7.22 !
Why hasn't it be commited yet ?

If you want to understand one of the usage of this patch :

  1. install drupal
  2. create a content type "test"
  3. add to "test" a required and multiple text field "multiple text"
  4. add to "test" a required and single text field "single text"
  5. on the node creation form, let your field empty
  6. look at the error messages

dp_multiple_fields_missing_title.png

DuaelFr’s picture

Version: 7.x-dev » 8.x-dev
Status: Reviewed & tested by the community » Needs review
Issue tags: -String freeze
FileSize
1.55 KB

7.x version is working very well but I know someone will ask for the 8.x version so here it is.

This patch is part of the #1day1patch initiative.

mgifford’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
41.59 KB

Followed the process in #31. Looks good to me now.

D8 errors multiple required form issues

yched’s picture

Status: Reviewed & tested by the community » Needs work

Sorry, but - the initial iterations of this patch, until #14, used #title_display to assign an invisible title, which is until that point was agreed as, and still is, the right approach (screen reader friendly, consistent with what is done in other places in core).

Then the issue stalled, and two years later, #24 restarted this with "I have this issue too, here is what worked for me" and a patch that completely overlooks the previous one. But #14 (adjusted in #20) is still the way to go.

What should happen here is reroll patch #20.

mgifford’s picture

Status: Needs work » Needs review
FileSize
1.26 KB

You definitely shouldn't be sorry @yched.. Definitely I should have caught that error..

It's confusing that single form elements seem to get piped through formMultipleElements()

Anyways, this inserts the labels back in.

It did make me wonder about adding fieldsets here around the table too. Not sure that is necessary though.

yched’s picture

Status: Needs review » Reviewed & tested by the community

Thanks @mgifford :-) Looks good to me.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, drupal_core-8.x-fix_multivalue_validation-980144-35b.patch, failed testing.

swentel’s picture

Status: Needs work » Needs review
swentel’s picture

Status: Needs review » Reviewed & tested by the community

Random failure

catch’s picture

Status: Reviewed & tested by the community » Needs review

Should this have test coverage?

jibran’s picture

Status: Needs review » Needs work

The last submitted patch, drupal_core-8.x-fix_multivalue_validation-980144-35b.patch, failed testing.

tim.plunkett’s picture

Here's a D7 backport for those in need. Still needs tests.

ACF’s picture

Added a test to catch this.

ACF’s picture

Stupid mistakes in 46.

The last submitted patch, 46: field-980144-46.patch, failed testing.

The last submitted patch, 46: field-980144-test.patch, failed testing.

The last submitted patch, 47: field-980144-test.patch, failed testing.

asgorobets’s picture

+++ b/modules/field/field.form.inc
@@ -213,14 +213,19 @@ function field_multiple_value_form($field, $instance, $langcode, $items, &$form,
+        $element['##description'] = '';

A little typo in #45.

Attaching updated patch for D7.

swentel’s picture

Issue tags: -Needs tests
FileSize
2.77 KB

Rerolled for PSR4

Status: Needs review » Needs work

The last submitted patch, 52: field-980144-52.patch, failed testing.

heddn’s picture

Issue summary: View changes
Issue tags: +Needs reroll, +Novice
DuaelFr’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll, -Novice
FileSize
2.72 KB

Status: Needs review » Needs work

The last submitted patch, 55: issues_with_required-980144-55.patch, failed testing.

DuaelFr’s picture

Assigned: Unassigned » DuaelFr

A lot of things changed in form structure so it's not just a basic reroll that's needed.
I'm on it.

DuaelFr’s picture

Assigned: DuaelFr » Unassigned
Issue summary: View changes
Status: Needs work » Needs review
Issue tags: +a11y, +Accessibility
FileSize
2.77 KB
2.35 KB
7.74 KB
7.46 KB
DuaelFr’s picture

Issue summary: View changes
mark_fullmer’s picture

Status: Needs review » Reviewed & tested by the community

Per patch in #58, placement of "required" asterisk is correct, both visually and in the source, for the textfield.

anavarre’s picture

+++ b/core/modules/field/src/Tests/FormTest.php
@@ -320,24 +320,24 @@ function testFieldFormUnlimited() {
+    entity_create('field_storage_config', $field_storage)->save();
+    entity_create('field_config', $this->field)->save();

Could we use the entityManager instead of entity_create()?

tim.plunkett’s picture

FieldStorageConfig::create($field_storage)->save();
FieldConfig::create($this->field)->save();
DuaelFr’s picture

@anavarre @tim.plunkett I think we should open an other issue for that change because it would make this test inconsistent with the other ones of the same class.

tim.plunkett’s picture

Using deprecated functions in new code is not a good idea. Consistency within a single method wouldn't even convince me, but within a same class? That's not a reason to write worse code.

DuaelFr’s picture

Assigned: Unassigned » DuaelFr
Status: Reviewed & tested by the community » Needs work

Let's work on a new patch then :)

DuaelFr’s picture

Assigned: DuaelFr » Unassigned
Status: Needs work » Needs review
FileSize
3.01 KB
1.04 KB
tim.plunkett’s picture

Fair enough :)

  1. +++ b/core/lib/Drupal/Core/Field/WidgetBase.php
    @@ -176,10 +176,21 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f
    +        $element = array(
    ...
    +        $element = array(
    

    Might as well use [] on new code.

  2. +++ b/core/lib/Drupal/Core/Field/WidgetBase.php
    @@ -176,10 +176,21 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f
    +          '#title' => $title . ' ' . t('(value @number)', array('@number' => $delta + 1)),
    

    $this->t() please

  3. +++ b/core/modules/field/src/Tests/FormTest.php
    @@ -317,6 +319,31 @@ function testFieldFormUnlimited() {
    +  function testFieldFormUnlimitedRequired() {
    

    public funtion

  4. +++ b/core/modules/field/src/Tests/FormTest.php
    @@ -317,6 +319,31 @@ function testFieldFormUnlimited() {
    +    $field_storage = $this->fieldStorageUnlimited;
    

    No real reason to create a new variable for this, we don't bother for $this->field

DuaelFr’s picture

Here is a new patch. There is a lot of existing code that migh be rewriten according to these rules. Should we open an issue somewhere?

tim.plunkett’s picture

Looks like this wasn't rebased properly (from 3kb to 40kb!)
You can open up a follow-up to modernize other code, though it might wait for 8.1.x.
I'm just against adding new code that follows obsolete standards.

DuaelFr’s picture

Oops sorry! That's what happens when working late :/

tim.plunkett’s picture

+++ b/core/lib/Drupal/Core/Field/WidgetBase.php
@@ -176,10 +176,21 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f
+          '#title' => $title . ' ' . t('(value @number)', array('@number' => $delta + 1)),

$this->t(), array() to []

Then it's RTBC!

DuaelFr’s picture

I should configure my IDE to warn me for all these things T_T

tim.plunkett’s picture

Status: Needs review » Reviewed & tested by the community

:)
Thanks! RTBC

alexpott’s picture

Version: 8.0.x-dev » 7.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Committed 2a4ea49 and pushed to 8.0.x. Thanks!

Thanks for the screenshots and beta evaluation in the issue summary.

  • alexpott committed 2a4ea49 on 8.0.x
    Issue #980144 by DuaelFr, yched, ACF, poedan, tim.plunkett, mgifford,...
DuaelFr’s picture

Status: Patch (to be ported) » Needs review
Issue tags: -Needs backport to D7
FileSize
1.67 KB
1.67 KB
DuaelFr’s picture

FileSize
3.01 KB

Whoops! Uploaded the same file twice ;)

The last submitted patch, 76: d7-issues_with_required-980144-76-tests-only.patch, failed testing.

The last submitted patch, 76: d7-issues_with_required-980144-76-tests-only.patch, failed testing.

star-szr’s picture

Looks like a solid fix! Thank you everyone who worked on this issue.

This doesn't necessarily matter too much for the backport, but just for the record in tests XPaths are definitely preferred over assertRaw for asserting markup with certain attributes. Using XPaths in general makes the tests much less brittle when it comes to changing markup. Refactored the added test to use XPath over here: #2473951-15: Prefix form-required classes with js-

DuaelFr’s picture

@Cottser @alexpott @tim.plunkett Do you think we should rewrite the D8 test to use xpath() instead of assertRaw() right now?

mgifford’s picture

Issue tags: -a11y

Would be great to have this backported! Mostly I'm removing the a11y tag as we're trying not to use that.

mgifford’s picture

Issue tags: +Needs reroll
star-szr’s picture

@DuaelFr sorry for the delayed response yes the D7 test should use XPath as well I'd say.

DuaelFr’s picture

Issue tags: -Needs reroll

@mgifford The patch in #77 still applies on 7.x for me.

@Cottser The D8 patch have been commited without using xpath. I suggest to stay consistent with that patch to ease future modifications. As changin that in D8 is probably going to be postponed to 8.1 I think we should not invest more time in that issue. The tests are working well as-is.

mgifford’s picture

@DuaelFr - sorry.. Realized I was just applying this patch to D8..

I added a multiple text field to user/1/edit pre & post patch. It's looking good!

So any concerns with marking this RTBC?

DuaelFr’s picture

No problem Mike.
If we agree about keeping the tests as-is I think we can RTBC that issue :)

mgifford’s picture

Status: Needs review » Reviewed & tested by the community

Ok, I just reapplied the patch to see that it all works still and marking it RTBC.

David_Rothstein’s picture

Status: Reviewed & tested by the community » Needs work

I tested this patch. When I tried to submit the form without filling out the required multivalued field, I got this error message:

My Field Name (value 1) field is required.

That's pretty confusing (although probably still better than the current behavior). Why isn't it just "My Field Name field is required"?

I guess we want the parenthetical part in there for the field label that screen readers use, but it doesn't seem like it should be part of the error message for non-screen-readers.

Something like #742344: Allow forms to set custom validation error messages on required fields might be a real solution, but possible independent solutions could include:

  • Leave the "value 1" part off the first label (only add it to the 2nd and beyond). This would solve the issue since only the first label is used in the error message. Is that OK for accessibility?
  • Make the titles look like My Field Name <span class="element-invisible">(value X)</span>. Kind of ugly (since the <label> has an element-invisible too so there will be a nested element-invisible) but maybe it makes sense - both regular users and screen reader users will get an error message that matches the field labels that are shown to them.
+        $element['#title'] = $title . ' ' . t('(value @number)', array('@number' => $delta + 1));

This doesn't look properly translatable. Shouldn't it be t(!title (value @number)')?

+    $this->assertRaw(format_string('<label>@label !required</label>', array('@label' => $this->instance['label'], '!required' => $required)),
+      'Required symbol added field label.');

Should be "Required symbol added to field label", I think?

+    $this->assertRaw(format_string('<label class="element-invisible" for="edit-@fieldname-und-0-value">@label (value 1) !required</label>', array('@fieldname' => strtr($this->field_name, '_', '-'),'@label' => $this->instance['label'], '!required' => $required)),
+      'Required symbol not added for field input.');

The assertion message doesn't match the code - it's actually asserting that a required symbol is present. We probably want to say something more like "Required symbol and field label are visually hidden".

David_Rothstein’s picture

Also per the above comments we should really backport the tests as they currently exist in Drupal 8 (with xpath). Doesn't really matter if that got originally committed to Drupal 8 in this issue or another; it's still the right thing to backport :)

Here's what's currently in Drupal 8:

    // Check that the Required symbol is present for the multifield 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.
    $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.');

Should be a good guide for backporting, although obviously the HTML that's being asserted is slightly different.

  • alexpott committed 2a4ea49 on 8.1.x
    Issue #980144 by DuaelFr, yched, ACF, poedan, tim.plunkett, mgifford,...

  • alexpott committed 2a4ea49 on 8.3.x
    Issue #980144 by DuaelFr, yched, ACF, poedan, tim.plunkett, mgifford,...

  • alexpott committed 2a4ea49 on 8.3.x
    Issue #980144 by DuaelFr, yched, ACF, poedan, tim.plunkett, mgifford,...
ultrabob’s picture

Is this the right place to watch for a fix to this to hit 7.x? Seeing a bunch of 8.x stuff at the end, I'm confused.

aerozeppelin’s picture

Status: Needs work » Needs review
FileSize
2.37 KB
2.89 KB

An attempt to update the patch as per comments in #91.

mgifford’s picture

@aerozeppelin - what about the issues in #90?

aerozeppelin’s picture

@mgifford Thank you for pointing it out. I've made updates to accommodate changes from #90.

Something like #742344: Allow forms to set custom validation error messages on required fields might be a real solution, but possible independent solutions could include:

- Leave the "value 1" part off the first label (only add it to the 2nd and beyond). This would solve the issue since only the first label is used in the error message. Is that OK for accessibility?
- Make the titles look like My Field Name (value X). Kind of ugly (since the has an element-invisible too so there will be a nested element-invisible) but maybe it makes sense - both regular users and screen reader users will get an error message that matches the field labels that are shown to them.

I wasn't sure what option to choose in this case. I chose option one for no specific reason. Any thoughts ?

DuaelFr’s picture

The code looks good.
I didn't test it manually though.

mgifford’s picture

Thanks @aerozeppelin

I'm not actually sure about the accessibility. I'd need to look at it more or see an example.

If a required field is required, it should indicate that. Perhaps not visually (if it is clear in other ways), but semantically.

dxvargas’s picture

I did test it manually and patch #98 works good!

@mgifford can you be more precise about the changes you recommend? I didn't fully understood what you're asking for.
Anyway, let me ask: Was your request fulfilled before and it stopped being fulfilled after applying this patch? Could that improvement be done in a new issue?

I would mark this as RTBC now. We should apply the patch and close this major bug ASAP, we have already a long story here and if one patch fixes the bug, please let's get on with it.

mgifford’s picture

@dxvargas - This is an improvement over D7 Core. I agree with the RTBC. Without the patch the "*" is repeated visually. With the patch it looks like this:

image of multi-field form

dxvargas’s picture

FileSize
6.63 KB

@mgifford I see your point.
For me the "*" next to the field is not important, because we have that signal next to the label, as usual.

The weird thing is that currently only one "*" is shown next to one field and the others don't count. Any field once filled should be enough. Even if one of the text fields is filled but it is missing the "*" field, then we have the error saying the field is required.
Screenshot
So, again in my opinion, this should be fully thought and worked in a new issue.

mgifford’s picture

@dxvargas I agree that the issue with error messages for multiple fields needing its own issue. The problem you described is also an issue in 8.3.x. Not that it gives you the same error (there's an HTML5 required element that pops up), but that error only happens on the first field.

We should discuss if it is:

  • Any field once filled should be enough
  • All fields are filled in
  • All open fields are filled in (unlimited fields have to be negotiated)
  • Only the first one needs to be filled in.

But this isn't the place for this. It also doesn't seem like it would be an accessibility issue, but rather general behavior.

Can you open up a new issue for D8.3 and mark this current one RTBC for D7?

ademarco’s picture

Status: Needs review » Reviewed & tested by the community

I've tested it and patch #98 works fine for me too, marking it as RTBC as requested.

  • alexpott committed 2a4ea49 on 8.4.x
    Issue #980144 by DuaelFr, yched, ACF, poedan, tim.plunkett, mgifford,...

  • alexpott committed 2a4ea49 on 8.4.x
    Issue #980144 by DuaelFr, yched, ACF, poedan, tim.plunkett, mgifford,...
stefan.r’s picture

+++ b/modules/field/field.form.inc
@@ -213,14 +213,25 @@ function field_multiple_value_form($field, $instance, $langcode, $items, &$form,
+          $element['#title'] = t('!title', array('!title' => $title));

This t() is not really doing anything here

mgifford’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +SprintWeekend2017, +SprintWeekend2017a11y

We need a new patch then.

dxvargas’s picture

IMHO reopening an issue that was created in 2010 and it has a patch that has already been merged, only because there is a t() that is doing nothing, is not the best option.

mgifford’s picture

@dxvargas I don't know what has changed.. Can't we just re-roll the patch and take out the t()?

ultrabob’s picture

The issue has not been reopened, it is a 7.x issue and there is not 7.x patch that has been committed so far as I can tell.

Edit: Sorry rereading the thread I see that you probably mean it doesn't make sense to remove RTBC for this issue.

seren10pity13’s picture

Hi,
To solve the problem of required multiple fields not showing the field name on validation, I preferred using a custom module and a HOOK to avoid problems when updating :

/**
 * Implements HOOK_field_widget_form_ALTER() 
 * from drupal_alter(array('field_widget_form', 'field_widget_' . $instance['widget']['type'] . '_form'), $element, $form_state, $context);
 * defined in /modules/field/field.form.php : function field_multiple_value_form()
 */
function HOOK_field_widget_form_alter(&$element, $form_state, $context) {
	if( isset($element['target_id']['#title']) && empty($element['target_id']['#title']) ){
		$element['target_id']['#title'] = $context['instance']['label'];
	}
}

It did the job for me. Hope it helps.

Status: Needs review » Needs work

The last submitted patch, 114: 980144-114.patch, failed testing.

therobyouknow’s picture

Thank you aerozeppelin - my colleague and I have also found Patch #98 to work for our entity reference field set to mandatory.

By works I mean that "field is required" error message (i.e. without the actual field name shown/missing) now has the field name in the error message shown after attempting to save the content with the field empty.

We are now doing more testing to ensure hopefully no side effects in applying the patch (regression testing).

Thanks again, given that this has been available for a few months, hopefully this can be included in a forthcoming update to core soon.

For now, the patch is very welcome thank you. I'll let you know if we have any findings from our regression testing.

joelpittet’s picture

Status: Needs work » Reviewed & tested by the community

I've tested this as well and it works perfect for entityreference with multiple values.

Before it would not have a title and after it would, no duplication on the form.

jelo’s picture

Same on my site. Fixes issues with multiple values in entityreference fields.

ultrabob’s picture

RTBC++ The patch takes unlimited value entity reference fields from being completely unable to delete entries to being usable again. I hope it can be committed soon so I can stop tracking that this patch is required for all my sites.

jelo’s picture

Any chance that this can get committed? It seems like the community reviewed the patch and confirmed it is working...

andrewmacpherson’s picture

I queued a re-test, the patch is a year old. It's been at RTBC for 6 moths though, so worth bumping.

MustangGB’s picture

Patch applies cleanly, RTBC+.

Vacilando’s picture

RTBC+

MustangGB’s picture

Issue tags: -SprintWeekend2017, -SprintWeekend2017a11y +Drupal 7.60 target
joseph.olstad’s picture

Issue tags: -Drupal 7.60 target +Drupal 7.61 target

Bumping to 7.61, this didn't make it into 7.60

joseph.olstad’s picture

joseph.olstad’s picture

MustangGB’s picture

Issue tags: -Accessibility, -Drupal 7.64 target +accessibility, +Drupal 7.65 target
tim.plunkett’s picture

Issue tags: -accessibility (duplicate tag) +Accessibility

Fixing tags

darkodev’s picture

Perhaps we should have a standard by which we reference the comment when we thumbs up a patch?

Is https://www.drupal.org/project/drupal/issues/980144#comment-11954051 the latest patch everyone is using? I can't tell from comments if they are referencing the updated version or the original at https://www.drupal.org/project/drupal/issues/980144#comment-11695545

Any update on getting this into the next release, please, please?

darkodev’s picture

#114 applies cleanly to 7.65

darkodev’s picture

RTBC+

MustangGB’s picture

Issue tags: -Drupal 7.65 target +Drupal 7.68 target
joseph.olstad’s picture

joseph.olstad’s picture

MustangGB’s picture

Issue tags: -Drupal 7.68 target +Drupal 7.69 target
MustangGB’s picture

Issue tags: -Drupal 7.69 target +Drupal 7.70 target
voleger’s picture

mcdruid’s picture

Issue tags: -Drupal 7.71 target +Pending Drupal 7 commit

Patch for review is #114 which passes all tests.

D8/9 commit for comparison was https://www.drupal.org/commitlog/commit/2/2a4ea49e9c4eb88bfbc30a18588d4f...

I think this looks good, other than we don't need t() around the messages in the assertions:

+    $this->assertEqual($result[0], '*', t('Required symbol added to 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.                   
+    $result = $this->xpath("//label[contains(@class, 'element-invisible') and contains(text(), :label)]/span/text()", array(':label' => $this->instance['label']));
+    $this->assertEqual($result[0], '*', t('Required symbol and field label are visually hidden.'));

That can be fixed on commit if it's the only problem.

Fabianx’s picture

RTBC + 1, except for the t() I agree with that change, we usually use format_string().

This should also improve things for screenreaders unless I miss something. (Yeah, just saw the Accessibiltiy tag)

+1000

joelpittet’s picture

RTBC +1 #113 for a while too.

  • mcdruid committed ab6168b on 7.x
    Issue #980144 by DuaelFr, yched, ACF, aerozeppelin, poedan, tim.plunkett...
mcdruid’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: -Pending Drupal 7 commit

Removed the t() functions in the test's assertions on commit.

Thanks everyone!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

codebymikey’s picture

This seems to have broken the "Edit summary" behaviour on Long Text with Summary fields with multiple cardinality.

https://stm60fecf90ca939-kv5vfpdqprkhiplfwfkqskyhd8w9ukjg.tugboat.qa/nod... (7.80):
Behaviour on 7.80
https://stm60fecfa319da7-kx6gxlnflq7ymq2kz4ibtmcw5imklyjw.tugboat.qa/nod... (7.82):
Behaviour on 7.82

The same bug exists on D8/D9 (#2817081: Show 'Edit summary' links on multi-value long text field with summary) presumably because of that same commit.

NB: The tugboat instance might expire after a couple of days.
Login credentials are u:admin p:admin.

codebymikey’s picture