Despite many features, one
big shortcoming of the Typeahead is an insufficient WAI-ARIA support
(I would say it was completely missing until now). An AutoComplete
widget should be designed to be accessible out of the box to users of
screen readers and other assistive tools. I have decided to add a
fully WAI-ARIA support, done this taks and sent my pull request to
the GitHub. Below is the new "WAI-ARIA aware" markup with
an explanaition (not relevant HTML attributes are omitted).
<input class="typeahead tt-hint" aria-hidden="true"> <input class="typeahead tt-input" role="combobox" aria-autocomplete="list/both" aria-owns="someUniqueID" aria-activedescendant="set dynamically to someUniqueID-1, etc." aria-expanded="false/true"> <span id="someUniqueID" class="tt-dropdown-menu" role="listbox"> <div class="tt-dataset-somename" role="presentation"> ... <span class="tt-suggestions" role="presentation"> <div id="someUniqueID-1" class="tt-suggestion" role="option"> ... single suggestion ... </div> ... </span> ... </div> </span> <span class="tt-status" role="status" aria-live="polite" style="border:0 none; clip:rect(0, 0, 0, 0); height:1px; width:1px; margin:-1px; overflow:hidden; padding:0; position:absolute;"> ... HTML string or a precompiled template ... </span>
The first input field with
the class tt-hint simulates a visual hint (s. the picture above). The
hint completes the input query to the matched suggestion visually.
The query can be completed to the suggestion (hint) by pressing
either right arrow or tab key. The hint is not relevant for the
screen readers, hence we can apply
the aria-hidden="true" to
that
field. The hint is ignored by screen readers then. Why is
it not important? Because
we will force reading
the matched suggestion more
intelligent
by the "status" area with aria-live="polite"
(will be explained below).
The
next input field is the main
element
where the user inputs query. It
should have a role="combobox". This is a recommended role
for an AutoComplete. See
the official WAI-ARIA docu
for more details.
In fact, the
docu also shows a rough
markup structure of an AutoComplete!
The property aria-expanded indicates whether the list with suggestions is expanded (true) or collapsed (false). This property will be updated automatically when the list's state changes.
The list with suggestions itself should have a role "listbox". That means, the widget allows the user to select one or more items from a list of choices. role="option" should be applied to individual result item nodes within the list. There is an interesting article "Use "listbox" and "option" roles when constructing AutoComplete lists", which I suggest to read. Not important for the screen readers parts should be marked with role="presentation". This role says "My markup is only for non sightless users". You probably ask, what is about the role="application"? Is it important for us? Not really. I skipped it after reading "Not All ARIA Widgets Deserve role="application"".
The last element in the markup is a span with the role="status" and the property aria-live="polite". What it is good for? You can spice up your widget by letting the user know that autocomplete results are available via a text that gets automatically spoken. The text to be spoken should be added by the widget to an element that is moved outside the viewport. This is the mentioned span element with applied styles. The styles are exactly the same as the jQuery CSS class ui-helper-hidden-accessible, which hides content visually, but leaves it available to assistive technologies. The property aria-live="polite" on the span element means – updates within this element should be announced at the next graceful interval, such as when the user stops typing. Generally, The aria-live property indicates a section within the content that is live and the verbosity in which changes shall be announced. I defined the spoken text for the AutoComplete in my project as an JavaScript template compiled by Handlebars (any other templating engine such as Hogan can be used too).
Handlebars.compile( '{{#unless isEmpty}}{{count}} suggestions available.' + '{{#if withHint}}Top suggestion {{hint}} can be chosen by right arrow or tab key.' + '{{/if}}{{/unless}}')When user stops to type and suggestions are shown, a screen reader reads the count of available suggestions and the top suggestion. Really nice.
Last but not least is the testing. If you do not already have a screen reader installed, install the Google Chrome extensions ChromeVox and Accessibility Developer Tools. These are good tools for the development. Please watch a short ChromeVox demo and a demo for Accessibility Developer Tools too. Alternative, you can also try a free standalone screen reader NVDA. Simple give the tools a try.
thanks for sharing informative post..Keep updating your blog.
ReplyDeleteHi,
ReplyDeleteI find this feature very interesting, and I would like to implement it in my JSF-project. Right now I am using primefaces autocomplete, but it has some bugs/flaws wich almost makes it unusable.
Do you have a little demo-project for this example? I tried to implement different autocomplete-widgets, unfortunately unsuccessful.
I would be very thankfull if you could share some code snippets or a little demo project.
--
Julian
I have a composite component for that, but the code is private (belongs to the company, I'm currently working for).
DeleteWe plan to add this compoment to PrimeFaces Extensions. There is a task there, in the bug tracker. But my time is limited currently.
I understand, it would have been surplus anyway to share the code. One question though, how do you pass the data from the bean into the javascript?
DeleteSee http://ovaraksin.blogspot.de/2014/07/how-to-get-json-response-from-jsf.html
DeleteHm, I prepared everything just like in your post. Still I do not understand how to bind the json to the typehead dataset.
ReplyDeletevar numbers = [...] this is where i need the json object and I dont understand how to bind my data.
Thanks for this infor
ReplyDeleteby : web development company in the Philippines