Tuesday, June 26, 2007

Accessibility, TABINDEX, ACCESSKEY and a weird Apex quirk

I am eventually back to my desk after an exciting week spent traveling across USA, where most of my time was spent either on a aircraft or in a queue waiting to be searched by security agents, plus a couple of days in Daytona Beach, at the ODTUG Kaleidoscope 2007, so now you know why i didn't update my blog in the last 9 days.
Actually if i reckon all the hours wasted in the long lines of people at the airports, i could have written a dozen new blog entries!

You can find a variety of detailed comments on the ODTUG Kaleidoscope 2007 in other blogs, see the work done by Dimitri Gielis for example (by the way, thank you Dimitri, i enjoyed the meetings with you and the other APEX gurus!), including photos of the attendees and snapshots of the slides being shown.

Even if many of the topics were already known to me, it was an opportunity to learn about certain details that i had overlooked in the past and HTML's TABINDEX attribute is one of such cases.
Scott Spendolini, President of Sumnertech, included a reference to this form element property in his presentation (that spanned many aspects of Oracle Application Express by the way) and i realized that i had never paid too much attention on web accessibility issues previously.

TABINDEX plays an important role in the keyboard navigation of a web page and you can read more about the rules that a W3C HTML 4.0 compliant browser should follow when it comes to move the so-called cursor focus.

If you are mousaholic, it can be of scarce importance to you, however there are a lot of people out there, especially the visually impaired ones, who are forced to use this approach when browsing pages, consisting in hopping from one form element to the next one, in the order specified by the various TABINDEXex, so it is something that you might want to consider carefully when creating pages with Oracle APEX.

Not only, if you are developing web pages on behalf of governmental institutions, you may be bound to certain standards like Section 508 of the Rehabilitation Act in the USA or other similar requirements by other countries.

If you are not yet convinced, then imagine that your mouse breaks down or it runs out of batteries and you there are no replacements at hand.

You could be forced to navigate web sites using the keyboard.
So it is not something that you can quickly dismiss without any concerns.

There is nothing particularly difficult in the subject but it is important to understand how the whole thing works in an APEX page, where there is no specific TABINDEX property defined as such, with the only exception of the page level property called Cursor Focus, that allows either to set the focus on the first item of a page (in Apex Region/Items order) or to not focus any particular item.

So, how does a typical Apex page work as far as TABINDEX is concerned?

If you look at the page source of an Apex page, you will find a lot of elements with TABINDEX="999", that is default value provided by Apex.
If you opted for having the focus on first item of page, then you should find a script element near the bottom of the page that looks like the following:
<script type="text/javascript">
<!-- first_field('item');


Where item is the name of the first item in the displayed sequence of items defined in Apex.
As you see, Apex doesn't tamper with TABINDEXex to obtain the result but instead it uses a javascript program to show the cursor in the relevant position.

However, while working on this topic, i found out a really strange quirk affecting this configuration setting. The problem seems to be known to some extent, i found a couple of messages in the OTN forum where people talk of a similar problem but the real reason was not clearly identified, so i invested some time to figure out where was the catch exactly.

I could not try with other Apex versions, so what i am saying applies to version basically, however i do believe that it holds for previous ones as well.

In short, this piece of Javascript is not included even if you selected the relevant option as outlined above, when the item on which you want to put the focus is of type "text field always submits page when Enter is pressed".

In other words, if item P1_XXX is of that special type *AND* it is also the first one to be displayed, then it cannot receive the focus because, for some unknown reason, the link to the javascript code will be omitted.

Is it a bug or is it a feature? Don't ask me.

Aside from this Apex alleged quirk, the general rule (explained in the document linked above) defines that the focus will move between items in character stream order, that is in order of appearance within the HTML source files when all TABINDEX values are the same and, by default, in APEX they are all set to 999.

If the focus is on the first element of the page (whatever this means...), pressing the TAB keys (TAB or SHIFT TAB), will take you to the next or previous element as they appear in the source file, which can be a consistent behavior for most pages actually.

Frankly speaking i made several attempts with different browsers in order to understand if their behavior was consistent with the aforementioned rules but i had to give up.

It seems to me that both latest versions of Internet Explorer and Firefox do not follow these rules when it comes to decide which element is the first to receive the focus, but once you have manually set the focus on some page element, then the cursor is moved consistently according to the rules.

So, unless you are satisfied with the built-in order that comes off the region/items sequencing combination, you may want to rearrange items using a different order that is more consistent from the user experience point of view.

For instance, if you have a page where the main input fields items are in a central region surrounded by other regions and items on both sides, you are probably better off setting the TABINDEX of each page item manually.
Enabling cursor focus on the first item of a page doesn't interfere with TABINDEX ordering although you can easily achieve inconsistent settings because there is no direct relationship between Apex's item sequence and the TABINDEX values you define in the item's attributes.
For example, you may have a page where you set TABINDEX="10" for the first item displayed and TABINDEX="1" on an the fifth element displayed.
Clearly this doesn't make much sense, but there is nothing to stop you from doing it.

Setting TABINDEX or ACCESSKEY (see below for more on ACCESSKEY) is accomplished in the following ways, depending on the item element type:

  1. Standard items:

  2. Standard buttons (either HTML, image or template based buttons):

  3. Special button items (HTML buttons):
  4. Special buttons (image or template based buttons):

Note that if you click on the Attributes label in these forms, the online help will suggest exactly this type of usage for this attribute property. Also, in order to successfully set the property, the button template must contain the #BUTTON_ATTRIBUTES# substitution string.

All right, but what kind of page elements come with this TABINDEX attribute?
As per the W3C document, eligible HTML tags are only: A, AREA, BUTTON, INPUT, OBJECT, SELECT, and TEXTAREA.

  • A maps to links, either internal pages or external URLs, including pop-up select lists and date pickers, as well as image or template based buttons and labels with help.
  • AREA is not mapped to any built-in page element.
  • BUTTON maps to HMTL buttons (both for region and item buttons).
  • INPUT maps to text fields, checkboxes and radiobuttons in their various forms.
  • OBJECT is not mapped to any built-in page element.
  • SELECT maps to combo boxes in their various forms.
  • TEXTAREA maps to textarea items in their various forms.

Another thing worth mentioning is the fact that in Apex items are often preceded by a label.
If the label is created using a template and the template includes a link to a pop-up help window, you must consider that the link is made up of an A tag embedding an image or text and that it can receive the focus. If you look at one of these label templates you will probably see a hardcoded TABINDEX="999", if any.

Currently i don't know of any simple way of dynamically setting a different value for TABINDEXex contained in label templates, because the problem is to keep it in sync with the underlying form element's TABINDEX value. My guess is that both values should be the same in order to mantain a consistent navigation order, but probably the only way to do that is to update the label's TABINDEX property values by means of some javascript code that loops on the target elements at onLoad time. But this is easier to say than to do.

Finally, let's talk about ACCESSKEY. This attribute specifies a keyboard shortcut for quickly moving the cursor focus from one element to another. For instance, in a login page you could define value "P" as ACCESSKEY for the User ID text field and "P" for the password. This setting would allow a user to get to the desired field by pressing either ALT+U or ALT+P on a Windows PC equipped with an English version of Internet Explorer 7 .
Practically speaking, one can add ACCESSKEY definitions in the same way as TABINDEX (see pictures above).

Unfortunately this is pure academical theory.

The blunt reality is that browser implementations and language localization differences make ACCESSKEY completely unusable unless you are 100% sure of the browser version that users will use to navigate your application.

Just to make a short list of main ACCESSKEY usage problems i found so far:
  • ALT+D will not work because both IE and Firefox perform the address bar activation.
  • ALT+U will not work in spanish version of IE because it opens the Help (Ayuda) menu.
  • ALT+ char for any characters mapped to the built in menu functions will not work either (language edition dependent).
  • Firefox implemented changes between versions 1.5 and 2.0., apparently in 2.0 one must press SHIFT+ALT+char, and char must not be a number, but i could not get it to work, no matter what the character was in FF
  • in Safari for Mac O/S, you must use Ctrl+char supposedly, however a page working with IE and Opera failed to work for some unknown reason.
  • in IE7, when accesskey is attached to an A element, then you must also press Enter to follow the link.
  • probably many other amenities i had no time to try out.
A far more positive experience was with Opera browser, where a user can activate accessibility keys by pressing SHIFT+ESC first and the browser will display a preview list of all the available shortcuts, thereafter by pressing char the cursor focus can be set onto the desired element.

In the end, given the state of the art, i don't see how one can get ACCESSKEY to work reliably in mixed environments, so the only accessibility feature that one can reasonably implement in Apex remains the TABINDEX attribute.


nilesh said...

Is it possible to move tabindex in same page but in different html regions?..

Byte64 said...

Hi Nilesh,
TABINDEX has no direct relationship with APEX HTML regions, so you can set the values as you like most.

At any rate, the best thing is to verify the theory against the practice and see if it works out, when it comes to browsers i've learned to not take *anything* for granted.


yes you can!

Two great ways to help us out with a minimal effort. Click on the Google Plus +1 button above or...
We appreciate your support!

latest articles