Several months ago, after using Drupal sites for some time, I was surprised to find that some fields provide autocomplete functionality. I am an assistive technology user, and primarily use the JAWS screen-reader.

I noticed today that not only does autocomplete not function (e.g. free tagging), but that it can sometimes return undesirable results, as the unintentional Issue Tag "variable_get" at http://drupal.org/node/515236 shows.

Yahoo and Google have both implemented search suggestions accessible to screen-reader users (my only testing is with JAWS 10). Google's approach does not use ARIA, as it works in IE6. Yahoo's approach does use ARIA.

Suggestions:

1. Resolve the issue where screen reader users may unintentionally select an inappropriate item in an autocomplete field.

2. Improve the markup of autocomplete fields to make autocomplete functionality accessible to screen-reader users. This will likely be best accomplished by using ARIA.

Files: 
CommentFileSizeAuthor
#50 drupal.autocomplete-aria.50.patch2.8 KBsun
PASSED: [[SimpleTest]]: [MySQL] 27,414 pass(es).
[ View ]
#42 515262-aria-autocomplete-4.patch2.21 KBEverett Zufelt
PASSED: [[SimpleTest]]: [MySQL] 26,968 pass(es).
[ View ]
#38 515262-aria-autocomplete-3.patch1.96 KBEverett Zufelt
PASSED: [[SimpleTest]]: [MySQL] 27,003 pass(es).
[ View ]
#34 515262-aria-autocomplete-2.patch1.83 KBEverett Zufelt
PASSED: [[SimpleTest]]: [MySQL] 26,973 pass(es).
[ View ]
#32 Screenshot-Create Article | drupal7.dev_.openconcept.ca - Chromium.png69.47 KBmgifford
#30 515262-aria-autocomplete-1.patch1.79 KBEverett Zufelt
PASSED: [[SimpleTest]]: [MySQL] 26,976 pass(es).
[ View ]
#27 515262-aria-autocomplete-partial-2.patch1.13 KBEverett Zufelt
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 515262-aria-autocomplete-partial-2.patch.
[ View ]
#20 515262-aria-autocomplete-partial.patch967 bytesEverett Zufelt
PASSED: [[SimpleTest]]: [MySQL] 26,854 pass(es).
[ View ]
#7 autocomplete.js_.v1.patch684 bytesmgifford
Passed on all environments.
[ View ]

Comments

Everett Zufelt’s picture

Component:admin.module» javascript

Corrected component.

drewish’s picture

I'd never heard of ARIA before but a quick Google turned up: http://www.w3.org/WAI/intro/aria and that had http://www.w3.org/TR/wai-aria-primer/ which makes for a nice introduction to their approach.

drewish’s picture

Best quote from the primer—and one of my gripes with the current autocomplete:

The question you must ask is: "Why make such an investment in accessibility and have unproductive users?" All desktop users will benefit from ARIA.

Everett Zufelt’s picture

lilou’s picture

Issue tags:+screenreader

Add tag.

Everett Zufelt’s picture

Title:Autocomplete is not functional, and sometimes returns incorrect values, for screen-reader users» Autocomplete requires ARIA for screen-reader users
Issue tags:+aria

Autocomplete returning incorrect values for screen-reader users is a duplicate of #159762: Autocomplete errors on whitespace only.

To provide autocomplete functionality for screen-reader users we will need to add ARIA support to the autocomplete JS. Tagging and changing title.

mgifford’s picture

Status:Active» Needs review
StatusFileSize
new684 bytes
Passed on all environments.
[ View ]

Again I'm assuming it's mostly a matter of inserting the aria attribute 'aria-live="polite"' in the right place.

Looking at and extending the model for autocomplete listed here - http://www.mit.edu/~rjc/completionList.html

I also added 'aria-relevant="all"' as I think that the entire list would be potentially useful in terms of how it could be used.

This is mostly an example, but think it may do the trick. Needs testing.

Status:Needs review» Needs work

The last submitted patch failed testing.

mgifford’s picture

Status:Needs work» Needs review

testing if the bot was bust.

mgifford’s picture

I ran the CSS Unit Tests locally after applying the patches without problem.

mgifford’s picture

Ran into the same problem here - http://drupal.org/node/521904

Maybe simpletest doesn't like ARIA

mgifford requested that failed test be re-tested.

brandonojc requested that failed test be re-tested.

bowersox’s picture

+1 for adding ARIA markup to autocomplete. The code here looks simple and okay to me.

I have not tested in a screenreader so I hope someone will do that to verify it works as expected.

Also, it looks like we could use JS to add the aria-autocomplete="list" attribute onto the the input element so screenreaders would announce that the input field supports autocomplete. (See aria-autocomplete values).

bowersox’s picture

Now that we're past the UX/string freeze, what is the policy on issues like this one?

  • It is marked as a 'bug'.
  • It is only a 1-line (1-attribute) HTML code change.
  • It doesn't change the UX or strings.

So should we proceed with it? Or should we be marking these as drupal 8.x-dev?

mgifford’s picture

I'd like to think that any accessibility enhancements that we can make that don't change the functionality or display of D7 should still be possible to bring in.

With this and other ARIA issues I'd like to have some testing in popular screen readers but would expect we'd be able to bring them in (as heck accessibility enhancements for D6 were backported into releases D6 earlier this year).

It's a simple change if it will make a difference to the users. There are some questions about the impacts for validation, but ARIA adoption is becoming more widespread.

Re-test of autocomplete.js_.v1.patch from comment #7 was requested by mgifford.

Everett Zufelt’s picture

Version:7.x-dev» 8.x-dev

Looked at aria-autocomplete="list". This is only part of the solution. This tells AT that there is a list of values, but aria is also required to tell AT which of the list of suggestions is currently selected. At this time I believe that aria should be injected with jQuery, as it will break document validation.

Would be happy to provide support if someone wants to try to get this in before 7.x RC.

mgifford’s picture

Can this be brought into D7 using the Accessible Helper Module?

Everett Zufelt’s picture

Version:8.x-dev» 7.x-dev
StatusFileSize
new967 bytes
PASSED: [[SimpleTest]]: [MySQL] 26,854 pass(es).
[ View ]

The attached patch is a partial solution and is primarily to get something out there to use for testing. I could really use the assistance (likely briefly) of a jQuery guru to answer the question about the context for 'this' mentioned in the first todo in the patch.

1. Adds role="application" to container div for autocomplete widget.
2. Appends a span role="alert" class="element-invisible" to the end of the container.

Todo:

Add behavior to add / remove the selected item from the autocomplete list to the span. AT that supports ARIA live regions should read the content of the span.

Note: This is not a perfect solution, which would involve completely rebuilding the widget to be a semantic UI component using ARIA. However, this will work, is relatively clean and unobtrusive.

Everett Zufelt’s picture

I noticed #675446: Use jQuery UI Autocomplete. I tested out the jQuery UI autocomplete widget, which is no more accessible than our own. I think that this reinforces the argument of geting something built that works, if not a full ARIA implementation, for our custom autocomplete, and then to focus effort on assisting with improving the accessibility of the jQuery UI widget so that we can eventually switch to using it instead of our own.

mgifford’s picture

Your patch applies nicely. It doesn't interfere with autocomplete's use for sighted folks either.

Just gotta get your jQuery question answered.

merlinofchaos’s picture

To answer the TODOs, from skimming through the code, 'this' in the select, selectUp and selectDown functions will be the textfield <input> form widget.

merlinofchaos’s picture

To get the span you added, I believe you want this:

$($(this).attr('id') + '-autocomplete-aria-live')
merlinofchaos’s picture

Sorry, I was wrong. 'this' will be the jsAC object. So 'this.input' should contain the input textfield.

Everett Zufelt’s picture

@merlinofchaos

Thanks, this.input makes sense now.

@all

A couple further problems.

1. Autocomplete in beta1 w/o the patch doesn't appear to be working, testing with the tags field on articles. Can someone please confirm?

2. I can't install head since it now requires PHP 5.2.4 and my dev server doesn't support that. And there are a series of events that I do not have full control over that need to take place before I upgrade. If someone has access to a place that I can test the patch against head I'd appreciate it.

Everett Zufelt’s picture

StatusFileSize
new1.13 KB
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 515262-aria-autocomplete-partial-2.patch.
[ View ]

Attached a new partial patch.

1. Fixed added span, so that it actually gets the correct id.

2. Added an alert to the highlight function for testing. It * should * display the id of the span, it is displaying Undefined.

+alert($($(this.input).attr('id') + '-autocomplete-aria-live').attr('id'));

I thought the above line would work to get the id of the span, I was incorrect.

Status:Needs review» Needs work

The last submitted patch, 515262-aria-autocomplete-partial-2.patch, failed testing.

Everett Zufelt’s picture

Ok, @jacine helped me remember I need a '#' for an id selector. I am happy to report that the selected list item is currently being read to me in JAWS 11 / FF 3.6.

$('#' + $(this.input).attr('id') + '-autocomplete-aria-live').html($(this.selected).html());

The above line is what I am using to put the selected item into the invisible span to be read automatically by screen-readers that support ARIA live.

I will do a bit more tweaking and reroll a patch for testing tomorrow.

Everett Zufelt’s picture

Status:Needs work» Needs review
StatusFileSize
new1.79 KB
PASSED: [[SimpleTest]]: [MySQL] 26,976 pass(es).
[ View ]

This patch:

1. Sets role = application for the div containing the autocomplete element.
2. Sets aria-autocomplete = list on the text input element (Testing with NVDA 2010.1 and JAWS 11 neither reported this, but it is worth having)
3. Adds a span to the end of the div with aria-live = assertive (once we are done testing this can have class = element-invisible set
4. Adds behavior to add 'Autocomplete popup' to the span when the popup appears
5. As items are selected in the popup they are added to the span so that AT that supports aria live regions will announce them.

Other than tweaking / code cleanup I think this is good.

Everett Zufelt’s picture

I realized that the 'Autocomplete popup' message needs to be translatable. Can someone please point me to the docs to use t() in JS?

mgifford’s picture

It works. I've got it up on my sandbox http://drupal7.dev.openconcept.ca/

I did notice that some additional descriptive text is actually visible - "Autocomplete popup" is visible in some situations.

Screenshot is attached. I don't think it's a bad thing, just worth mentioning.

Everett Zufelt’s picture

@Mike

Yep, the span is exposed for testing, once we are ready to RTBC we can add class="element-invisible"

Everett Zufelt’s picture

Issue tags:-aria, -screenreader+string freeze
StatusFileSize
new1.83 KB
PASSED: [[SimpleTest]]: [MySQL] 26,973 pass(es).
[ View ]

Added class="element-invisible" to the aria live region span.
Added Drupal.t() to wrap the 'Autocomplete popup' string.
Tagging with string freeze

Everett Zufelt’s picture

Testing:

Pass = Autocomplete worked as expected
Fail = Same results as before patch, user can enter tags, but is unaware of autocomplete functionality

FF 3.6
JAWS 11.0.1467 = Pass
NVDA 2010.1 = Pass

IE 8
JAWS 11.0.1467 = PASS
NVDA 2010.1 = Fail (poor IE support)
System Access To Go = Pass ( http://satogo.com )

Safari 5
VoiceOver (10.6.3) = Fail (no live region support)

sun’s picture

Status:Needs review» Needs work
+++ misc/autocomplete.js 7 Nov 2010 04:10:27 -0000
@@ -16,6 +16,9 @@ Drupal.behaviors.autocomplete = {
+      $(input).parent().append($('<span class="element-invisible" aria-live="assertive"></span>').attr('id', $(input).attr('id') + '-autocomplete-aria-live'));

@@ -141,6 +144,7 @@ Drupal.jsAC.prototype.highlight = functi
+  $('#' + $(this.input).attr('id') + '-autocomplete-aria-live').html($(this.selected).html());

@@ -149,6 +153,7 @@ Drupal.jsAC.prototype.highlight = functi
+  $('#' + $(this.input).attr('id') + '-autocomplete-aria-live').html('');

@@ -166,6 +171,7 @@ Drupal.jsAC.prototype.hidePopup = functi
+  $('#' + $(this.input).attr('id') + '-autocomplete-aria-live').html('');

@@ -217,6 +223,7 @@ Drupal.jsAC.prototype.found = function (
+      $('#' + $(this.input).attr('id') + '-autocomplete-aria-live').html(Drupal.t('Autocomplete popup'));

1) The appended element should be assigned and made available to all other methods in this.$heading.

2) .html('') == .empty()

Powered by Dreditor.

Everett Zufelt’s picture

@Sun

1) The appended element should be assigned and made available to all other methods in this.$heading.

Can you point to an example where I can look to learn to do this? This seems a bit over my head, but I will give it a shot.

2. Will switch .html('') to .empty()

Thanks

Everett Zufelt’s picture

Status:Needs work» Needs review
StatusFileSize
new1.96 KB
PASSED: [[SimpleTest]]: [MySQL] 27,003 pass(es).
[ View ]

1. Sets role = application for the div containing the autocomplete element.
2. Sets aria-autocomplete = list on the text input element (Testing with NVDA 2010.1 and JAWS 11 neither reported this, but it is worth having)
3. Adds a span to the end of the div with aria-live = assertive and class = element-invisible
4. Adds behavior to add Drupal.t('Autocomplete popup') to the span when the popup appears
5. As items are selected in the popup they are added to the span so that AT that supports aria live regions will announce them.
6. Addresses both of @Sun's points in #36.

casey’s picture

Can't we follow jquery ui's approach on aria on autocomplete elements?

Everett Zufelt’s picture

@Casey

Thanks for the comment.

1. I tested http://jqueryui.com/demos/autocomplete/multiple.html and it was not accessible with a screen-reader, perhaps it is not using the most recent code?

2. We are considering replacing our autocomplete with jQuery UI, so I am not inclined to do much work at all on our custom solution. See #675446: Use jQuery UI Autocomplete.

3. I think it far more likely for this small change to get committed in D7 than a larger solution, which is what the jQuery UI code that you pointed me to looks to be doing.

bowersox’s picture

The patch in #38 looks great! The javascript code all looks good and it appears coding standards are met. The behavior appears to work as desired (I agree with Everett that VoiceOver doesn't handle it right but maybe a future version will support live regions).

@sun or anyone else ready to give a last review? I think this is RTBC material.

As far as future use of jQuery UI (#675446) we should work to make that accessible before switching to it. It makes good sense for us to include this patch here as a light-weight solution for D7, and make jQuery UI our longer-term strategy.

Everett Zufelt’s picture

StatusFileSize
new2.21 KB
PASSED: [[SimpleTest]]: [MySQL] 26,968 pass(es).
[ View ]

This patch adds to #38 a message announced only to screen-reader users Drupal.t('Searching for matches.'), when the throbbing class is added.

bowersox’s picture

I tested again and things work well. JAWS 10 on IE 7 announced the "Searching for matches" message as soon as the autocomplete started searching. After that it announced the "Autocomplete popup" and it read out the selections as I navigated through them.

One question: Should the t() string have a period at the end (eg "Searching for matches.")?

Otherwise, this looks good to me. I think we're ready for RTBC.

Everett Zufelt’s picture

@Brandon

Looking back at the patch I notice that I put a period on 'Searching for matches.' but not 'Autocomplete popup'. I am happy to reroll w/ or w/o the period if someone can point me to directions.

My reasoning, I believe, at the time was that 'Searching for matches.' is a sentence, whereas 'Autocomplete popup' is more of a label / announcement. But, I really don't know where to find guidance for string punctuation.

bowersox’s picture

It's probably good as-is. I just grep'ed around core. When there is a complete sentence, we end the string with the period included. When we just have a title ("Warning message") we don't include the period. So it looks like the patch is consistent with that.

bowersox’s picture

Can anyone give a second review so this can be RTBC?

@sun?

mgifford’s picture

Should I expect to hear 'Searching for matches' using VoiceOver in Mac OS X 10.6.5? I applied the patch, cleared the patches, but I don't get an alert that says that. I just get the text that is listed in the form.

I'm not familiar enough with what it should sound like to mark this RTBC. It certainly doesn't break functionality for sighted users. I'd be happy to mark it rtbc if it's a matter that it's doing no harm.

Has anyone else tested this with VoiceOver?

Everett Zufelt’s picture

@mgifford

From comment #35 "VoiceOver (10.6.3) = Fail (no live region support)" So, you shouldn't hear anything ever with voiceover.

mgifford’s picture

Status:Needs review» Reviewed & tested by the community

That's what I was hoping to hear. With that I'm willing to mark it RTBC.

sun’s picture

Status:Reviewed & tested by the community» Needs review
StatusFileSize
new2.8 KB
PASSED: [[SimpleTest]]: [MySQL] 27,414 pass(es).
[ View ]

Please try again with this one.

mgifford’s picture

@sun - I can't test this with JAWS or NVDA, but it looks just fine when applied to my local sandbox. The autocomplete functionality works well.

Thanks for the patch. Hopefully someone else will RTBC it after reviewing it with a screen reader.

Everett Zufelt’s picture

Status:Needs review» Reviewed & tested by the community

@Sun's patch in #50 looks to just be a code cleanup. Tested and working properly.

1. Sets role = application for the div containing the autocomplete element. This is to allow screen-reader users to be able to use arrow keys in the text field without them being trapped by the screen-reader.
2. Sets aria-autocomplete = list on the text input element (Testing with NVDA 2010.1 and JAWS 11 neither reported this, but it is worth having)
3. Adds a span to the end of the div with aria-live = assertive and class = element-invisible
4. Adds behavior to add Drupal.t('Searching for matches...') to the span, when the throbbing class is added.
5. Adds behavior to add Drupal.t('Autocomplete popup') to the span when the popup appears
6. As items are selected in the popup they are added to the span.

This will make autocomplete functionality usable by users of AT that supports the ARIA application role and aria-live.

webchick’s picture

Status:Reviewed & tested by the community» Fixed

This seems like a small patch that improves the UX for screen readers, and doesn't seem to have any impact for visual users.

Committed to HEAD. Thanks!

Status:Fixed» Closed (fixed)
Issue tags:-autocomplete, -string freeze, -accessibility

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