Updated: Comment #28
Problem/Motivation
Parts of this issue are already committed to D8 (see #6)
This is similar to a problem that occurs in the Link module (See http://drupal.org/node/1309768#comment-6320382).
The "for" attributes in the labels are not matching the id or name attributes in the input boxes, which causes failures for Section 508 accessibility. Here is an example of how this fails:
<label for="edit-field-workapp-resume-und-0">Resume <span class="form-required" title="This field is required.">*</span></label>
<input id="edit-field-workapp-resume-und-0-upload" name="files[field_workapp_resume_und_0]" size="22" class="form-file" type="file">
Just like the "Link" module problem, the id in the file input area has an appended string '-upload'. The "display" and "description" fields were not enabled when configuring the File field here and used the progress bar instead of the throbber.
Proposed resolution
Patch from #6: This patch is using process, possibly not ideal (see #11 and #16). It's because the label is on the parent element, the actual field is $element['upload'], ie a child. But that is a file upload field so the title is used for a different purpose. This patch updates the id of the field so that the parent label is given to the child, there is no other markup output for the parent so we don't get duplicate ids. (source: #12)
Issues raised and new proposal, #21 and #22: this ID gets added as a JavaScript setting and therefore breaks the JavaScript validation for allowed file extensions i.e. as set up later on in the same function.
A better way to fix this might be to change the label's "for" attribute to match the desired ID, rather than the other way around. This would probably just involve making some changes to theme_form_element_label() to be smart enough to allow elements to set an explicit "for" attribute for the label and not overwrite it if it's already set...
Remaining tasks
The regression is in Drupal 7 & 8 (the JavaScript-based validation of allowed file extensions doesn't work)... Can we find the code that's adding the -upload in the first place?
Would removing the concatenation of -upload from the js setting break things downstream after applying the patch?
Needs thorough going through and new patch (+ D7 backport)
User interface changes
N/A
API changes
N/A
Related Issues
Comment | File | Size | Author |
---|---|---|---|
#48 | file_field_form_label-1734716-48.patch | 1.3 KB | Chris Burge |
#39 | Screen Shot 2014-11-29 at 12.31.46 PM.png | 229.43 KB | mgifford |
#35 | file_field_form_label-1734716-35.patch | 1.71 KB | larowlan |
#35 | interdiff.txt | 1.64 KB | larowlan |
Comments
Comment #1
Everett Zufelt CreditAttribution: Everett Zufelt commentedThis should be relatively easy to solve. Changed to 8.x as this is where all new work is done.
Comment #2
tim.plunkettTagging.
Comment #3
larowlanComment #4
larowlanThis is tests only patch, should fail.
Comment #6
larowlanTest only fails as expected
And again with the patch + tests
Comment #7
larowlanComment #8
BarisW CreditAttribution: BarisW commentedPatch works as expected. When clicking the label, the file upload window opens and the 'for' value is correct.
Comment #9
Everett Zufelt CreditAttribution: Everett Zufelt commentedAgreed, applies and works.
Seems like a good candidate to backport to d7
Comment #10
conniemh CreditAttribution: conniemh commentedThank you so much larowlan, BarisW, and Everett for giving this your attention and effort!
Backporting the patch to D7 would be great if possible; I have been sidetracked by other projects and have not made the updated function for my template.php file yet. Patching core file module would be preferable.
Thanks again!
Connie
Comment #11
catchDoing this in preprocess doesn't feel right to me, can't it happen when building the form somewhere? Or can we find the code that's adding the -upload in the first place?
Comment #12
larowlanHi catch, it's not using preprocess, it's using process - do you have the same objection to that?
It's because the label is on the parent element, the actual field is $element['upload'], ie a child. But that is a file upload field so the title is used for a different purpose. This patch updates the id of the field so that the parent label is given to the child, there is no other markup output for the parent so we don't get duplicate ids.
/me cheekily sets status back.
Comment #15
larowlanForgot to switch status back
Comment #16
catchOK I spoke to chx and he didn't have a good reason not to do this here, so I've gone ahead and committed/pushed this to 8.x.
This would be a markup change so it'll need some consideration as to how backportable it is, but will leave that for David to decide.
Comment #17
dcam CreditAttribution: dcam commentedBackported #3 to D7.
Comment #18
dcam CreditAttribution: dcam commentedComment #19
xjm#17: file-label-508-d7-1734716-17.patch queued for re-testing.
Comment #20
Gábor HojtsyLooks like a good backport, thanks for the proof of fail with the test only.
Comment #21
David_Rothstein CreditAttribution: David_Rothstein commentedIn general changing IDs is OK to fix accessibility issues (outside code should not be relying on specific IDs anyway), but if you look at how $element['#id'] is used later on in this function, the patch is changing a lot more of them than necessary.
More to the point, this ID gets added as a JavaScript setting, so it totally breaks the JavaScript validation for allowed file extensions, i.e. as set up by this code later on in the same function
and as used by Drupal.behaviors.fileValidateAutoAttach() later on.
Comment #22
David_Rothstein CreditAttribution: David_Rothstein commentedI just checked that the regression is in Drupal 8 also (the JavaScript-based validation of allowed file extensions doesn't work).
Not sure if it makes sense to split that off to a different issue at this point, but rolling this patch back fixes it and it's clear we need a different fix here anyway, so I'm leaving it as part of this issue for now...
Anyway, wouldn't a better way to fix this be to change the label's "for" attribute to match the desired ID, rather than the other way around? I think this would just involve making some changes to theme_form_element_label() to be smart enough to allow elements to set an explicit "for" attribute for the label and not overwrite it if it's already set... (I actually even thought there was an issue for that in the queue already, but I can't find it at the moment.)
Comment #23
nod_tag even if not really a JS issue.
Comment #24
larowlanTagging
Comment #25
scottshipman CreditAttribution: scottshipman commentedIf you remove the concatenation of -upload from the js setting, would that break things downstream, after applying the patch?
Comment #26
dcam CreditAttribution: dcam commentedhttp://drupal.org/node/1427826 contains instructions for updating the issue summary with the summary template.
The summary may need to be updated with information from comments.
Comment #27
mgiffordJust wanted to chime in to say that Section 508 isn't the goal that Drupal is working towards. The global standard for accessibility is still WCAG 2.0 and the Drupal community is working to ensure that it is AA compliant. That being said, it's a real challenge and there are sometimes issues like this that slip through.
@larowlan or @dcam any suggestions on how to deal with the downstream issues that @David_Rothstein & @scottshipman raised?
Comment #28
larowlan@mgifford I'll see if I can prod someone at work to have a look at this
Comment #29
ekl1773Updated issue summary using comments.
Comment #29.0
ekl1773Updated issue summary using template. -ekl1773
Comment #30
mgiffordAdding related meta issue #2035139: [meta] Comply with WCAG guideline 4.1: Compatibility
Comment #30.0
mgiffordUpdated issue summary.
Comment #31
mgiffordComment #32
mgiffordTesting the patch again (just a re-roll) in D7. Then will set it back to D8 so that we can look at @David_Rothstein's concerns in #22.
Comment #33
mgiffordOk, that passed but as @David_Rothstein said
by making theme_form_element_label() allow elements to set an explicit "for" attribute for the label and not overwrite it if it's already set.
Comment #34
mgiffordThis is in Core now in D8 core/modules/file/file.module
I don't know if this presents a problem for the Javascript wrapper:
At the moment it just produces
<div id="edit-field-image-0-upload-ajax-wrapper">
I don't see where the commit message was for this code, but perhaps it was added elsewhere.
In anycase, the accessibility problem is fixed in D8 now. So it should be fine to move this back to D7.
Comment #35
larowlanFixes the issues with JavaScript wrappers/ajax etc
Comment #36
mgiffordI confirmed that this is still an issue in D7 Core and that this patch fixes the problem which is visible here /node#overlay=node/add/article
Comment #37
maikeru CreditAttribution: maikeru commentedThe patch seems to work ok for the first filefield, but not sure the patch fixes it for multiple filefields on the same page.
Heres what I get on my second one:
Comment #38
mgiffordOk, so it's a bit better, but we should figure out why it doesn't work for the second filefield.
Also, this should be tested for D8 as well.
Comment #39
mgiffordActually, just tested it and it seems to be working fine so setting this back to RTBC:
Need more information to be able to replicate issue in #37.
Comment #42
David_Rothstein CreditAttribution: David_Rothstein commentedThat was a bogus test failure, so back to RTBC for now. (I didn't review the patch myself.)
Comment #45
dcam CreditAttribution: dcam commentedComment #46
David_Rothstein CreditAttribution: David_Rothstein commentedThis looks and works great. And the regression in Drupal 8 indeed appears to have been fixed elsewhere, so I'm removing that from the title.
Committed to 7.x - thanks!
Comment #48
Chris Burge CreditAttribution: Chris Burge commentedThe 7.x commit from this issue has caused a regression, which causes AJAX file uploads to fail. I discovered this issue after updating from Drupal 7.35 to Drupal 7.36 when Plupload ceased to upload files over AJAX.
Preserving the original element ID for use in $form['form_build_id']['#value']['wrapper'] and $element['#prefix'] appears to be unnecessary. The $original_id variable first appeared in patch #35.
Patch attached that eliminates the use of the original element ID.
Comment #49
David_Rothstein CreditAttribution: David_Rothstein commentedLooks like we have these two issue so far:
#2466247: Drupal core 7.36 broke Filefield Sources Ajax upload previews (FileField Sources)
#2466475: Drupal core 7.36 broke IMCE for FileField Ajax upload previews (IMCE for FileField)
Is Plupload broken specifically? It didn't look to me like it would be.
The original goal was to change as little HTML as possible, and I'm not sure we want to go back on that and start changing wrapper IDs (we could break even more if we do that)...
We could consider just rolling this back, or something like #22.
But at this point we also have the problem that it's already out there so rolling it back could re-break things.
I guess what we missed here is that some modules are expecting a particular relationship between $element['#id'] and the Ajax wrapper ID, and that relationship is no longer true after this issue? I'm not sure that's a great assumption to make but perhaps they have no choice...
Comment #50
David_Rothstein CreditAttribution: David_Rothstein commentedI just posted patches on both the above issues that fix this by making those modules use the actual Ajax wrapper ID rather than assuming a particular structure for it. It seems like a clean way to fix this, and the patches appear to work correctly.
I also added a note about these issues to the release notes (https://www.drupal.org/drupal-7.36-release-notes) - thanks!
Comment #51
David_Rothstein CreditAttribution: David_Rothstein commentedLooks like FileField Sources Plupload was the culprit actually: #2466505: Drupal core 7.36 broke FileField Sources Plupload Ajax upload previews
Comment #52
Chris Burge CreditAttribution: Chris Burge commentedI agree that patching the affected modules is better than reverting the core commit from this issue. Patches for two of the affected modules tested successfully for me: #2466505: Drupal core 7.36 broke FileField Sources Plupload Ajax upload previews and #2466505: Drupal core 7.36 broke FileField Sources Plupload Ajax upload previews. @David_Rothstein - Thanks for working through this issue so quickly. I think we're OK to change the status of this issue back to Fixed.
Comment #53
David_Rothstein CreditAttribution: David_Rothstein commentedThanks for testing those! Yeah, let's close this again for now.
I did take a look through some other FileField Sources-related modules and found 4 others that look like they might be affected (I just added them all to the list at https://www.drupal.org/drupal-7.36-release-notes now). I didn't test any of them myself, but did put up patches for each for people to test, if anyone is using those modules - since the code for the patch looked like it would be a completely straightforward extension of the code used to fix the other modules.
Comment #55
David_Rothstein CreditAttribution: David_Rothstein as a volunteer commentedNote that we're probably going to have to roll this back and fix it differently after all. See discussion/analysis in #2594955: [D7] Duplicate HTML IDs are created for file_managed_file fields
Comment #56
alexdoma CreditAttribution: alexdoma commentedAfter using patch #35 label starts works correct for first time. But with ajax we still get wrong for attribute.
Maybe it will helps to somebody.