public interface TabOrderOverview
The TabIndexManager
class
is a singleton class responsible for maintaining the tab order for a chain of elements, and
parcelling out tab index values. This class is not directly responsible for updating any
elements in the DOM - instead it associates a unique ID with a position in a hierarchical data structure
, and provides APIs to
restructure and reorder entries in the tree, request a numeric tab index value for each entry,
and fire a notification method when an entry's tab index changes due to the tree being
restructured.
The actual tab indices are lazily generated when requested, and will be slotted within the "auto-generated tab index" range (see Canvas.TAB_INDEX_FLOOR and TAB_INDEX_CEILING). A gap will be left between the assigned tab indices to minimize needing to reshuffle due to slotting elements before already assigned tab-indices, and logic is in place to handle reassigning tab indices to accomodate this if it does become necessary.
A notification method will be fired if any calculated tab index becomes obsolete due to the tree structure changing (either a parent is moved or we run out of space between elements and have to reassign indices to later elements).
Each Smart GWT Canvas uses its own ID to register
with the TabIndexManager at creation time and has built in logic to update its position in the
as the page structure changes, and, for focusable widgets, ensure the returned tabIndex value
is assigned to the widget handle. FormItem
s and
FormItemIcon
s are similarly registered with
TabIndexManager and apply the returned tab index to the appropriate element on the page.
By default canvas tab positions are updated as follows:
Canvas.getChildTabPosition()
. Note
that this method is overridden for Layouts to have tabbing occur in specified member
order.DynamicForm.sortItemsIntoTabOrder()
and FormItem.getIconTabPosition()
for details on how the TabIndexManager is integrated with
FormItems and FormItemIcons. Note that for canFocus false widgets, or widgets with tab index explicitly specified as either -1 or some value below TAB_INDEX_FLOOR will still be present in the TabIndexManager's data tree (we'll just never request a tab-index for them). This allows us to manage the tab index of their children in a logically consistent manner
Custom Tab order Tabbing behavior for canvases may be customized in a number of ways:
Canvas.tabIndex
may
be specified for any canvas. This is appropriate for very simple customizations only. It will
not impact the tab-index of any child, so to build an intuitive user experience using explicit
tabIndex values typically requires an explicit tabIndex be specified for every focusable
element on the page. Canvas.setRelativeTabPosition()
method may be used to assign a custom relative, or "local" tab position for a canvas. This
is the position within the canvas's parent widget, or within top level widgets if the
canvas has no parent or Canvas.updateTabPositionOnReparent
is false. TabIndexManager.moveTarget()
method and
pass in the canvas' ID as the first parameter.Canvas.updateTabPositionOnDraw
or reparent (see Canvas.updateTabPositionOnReparent
). To achieve this, a (unique) entry for each focusable component would be added to
the TabIndexManager at the desired location in the tab sequence tree.
For example, if a
focusable element is being written into some Canvas as part of its contents, you might
override Canvas.draw()
to add a new entry for
the element to the TabIndexManager, passing the canvas' ID as the parentID parameter. A call
to TabIndexManager.getTabIndex()
would then retrieve a numeric index that could be written into
the native HTML. You'd also want to provide a callback to update the element's native tabIndex
when the TabIndexManager creates a new numeric value for it. If you want to support programmatically tabbing
into the
element, a shiftFocusCallback should also be provided to put focus into the element, or
return false if this is not currently possibly for some reason.