-
Notifications
You must be signed in to change notification settings - Fork 17
WTab
WTab is a component for creating a single tab within a WTabSet. For each WTab a tab opener control will be created along with a panel for the tab's content.
- Using WTab
- Creating a WTab
- Accessibility
- Usability
- Open state
- Disabling
- Hiding
- HTML output
- Future developments
- Related Components
- Further information
WTab is only used within a WTabSet. Each WTab represents an independent section of content where the user is not constrained as to the order in which they may consume or interact with that content.
WTab hmay only be instantiated by adding a tab to an instance of WTabSet using one of the addTab
methods. All require a content WComponent. The "label" of the tab must be provided and may be s String or WDecoratedLabel. The TabMode may be provided (this was required before v 1.4.7, after this version the default if not provided is TabMode.LAZY) and an accesskey may be provided.
// Given WTabSet `tabset`
// create a WTab using
// content component `tabContent` and
// label text "Settings"
WTab tab = tabset.addTab(tabContent, "Settings");
// Before 1.4.7 the TabMode Was also required.
// To use WTabsSet.TabMode.CLIENT:
WTab tab = tabset.addTab(tabContent, "Settings",
WTabSet.TabMode.CLIENT);
WTab uses the WTabSet.TabMode
property to determine how the WTab's content is loaded. The mode enum is a member of WTabSet but the mode is determined per WTab not per WTabSet. This is important in ensuring optimal performance and the mode should be explicitly specified for every WTab. All of the modes described in Ajax modes are available to WTab.
The default mode is LAZY which provides a reasonable compromise amongst page load-size, performance and user experience but is by no means optimal for all use-cases.
The mode may be set using an appropriate constructor or the setter setMode(WTabSet.TabMode)
.
// Given WTabSet `tabset`
// Create a WTab of mode EAGER
WTab eagerTab = tabset.addTab(someComponent, decoratedLabelTabLabel,
WTabset.TabMode.EAGER);
// set the mode of WTab `tab` to DYNAMIC
tab.setMode(WTabSet.TabMode.DYNAMIC);
The tab's "label" is also its opener control and is created from a WDecoratedLabel component. This component may be specified by using one of the constructors which accept a WDecoratedLabel argument or is created implicitly if the WTab is created using one of the constructors which accepts a String "label" argument. In this latter case the String is used to populate a WText used as the body
component of a WDecoratedLabel.
If the opener control is required for manipulation it may be obtained from the instance of WTab using getTabLabel()
.
// get the label/opener control
//from WTab `tab`
WDecoratedLabel label = tab.getTabLabel();
The opener control may be manipulated using the members of WDecoratedLabel. The text of the "label" may be set using a proxy on WTab - setText(String)
. See WDecoratedLabel - adding content for caveats and restrictions on this as the proxy is an exact proxy for WDecoratedLabel's setText(String)
method.
// set the label text to "Issues"
issuesTab.setText("Issues");
The tabContent of a WTab may be any other WComponent. Most commonly this would be a WContainer or a container component such as a WFieldLayout, WFieldSet or WPanel.
A content component is required for all available constructors. The content may be accessed from an instance of WTab using the getter getContent()
. This returns a WComponent which may then need to be caste to be useful.
The content may be set using the setter setContent(WComponent)
. A WTab may ony have one content component therefore using setContent on an existing tab will replace the content component passed in as a constructor argument with possibly unforeseen side effects.
Each tab opener has a WAI-ARIA role of tab
and all of these for a given WTabSet are output into a container with the WAI-ARIA role of tablist
). The tab content is output into a container with a WAI-ARIA role of tabpanel
.
The tablist
for a WTabSet of TabSetType.ACCORDION has the WAI-ARIA attribute aria-multiselectable
. This attribute has value true
if multiple tabs in the tabset may be open at the same time or false
if only a single accordion tab may be open at a time (see WTabSet - open tabs).
All styling and controller actions are then determined by these WAI-ARIA roles and properties and set and reflect WAI-ARIA states appropriate to the role. An open tab, for example, is predicated solely on its state as reflected in appropriate WAI-ARIA states. An open tab in an ACCORDION
has the state aria-expanded="true"
and an open tab in a tab set has the state aria-selected="true"
.
Keyboard interactions of tabs are generally as outlined in the WAI-ARIA authoring practices:. Most notably for new users unfamiliar with keyboard driving a web application one navigates through a tab list using the arrow keys whereas the TAB key moves out of the tab list.
CTRL + UP, CTRL + PAGE_UP and CTRL + PAGE_DOWN are currently implemented as described in the WAI-ARIA authoring practices:. These are rather controversial and the benefits of support should be weighed against any possible accessibility problems they may cause. It is unlikely that these keystrokes would cause a user to be unable to use their tabbed browser but it is a possibility. Therefore we may remove this support: your input into this is welcome.
The "label" of a WTab is the content of the tab opener. The content of the tab opener must be appropriate to label the tab, explaining its purpose succinctly and providing sufficient context to the user to allow them to understand the likely use of the tab when the tab content is not available to them.
This label content is commonly text but may be a graphic or icon so long as the content has appropriate [text-equivalent accessible markup]http://www.w3.org/TR/UNDERSTANDING-WCAG20/text-equiv.html). Text-equivalence may be provided using an image alt attribute (if the opener content is an image), but as the interactive control is the opener itself it is better applied to the WTab using the toolTip
or accessibleText
properties.
See toolTip. A WTab may use the toolTip
property if it is not possible to include text content in the opener component.
// given WTab `tab`
// to set the toolTip
tab.setToolTip("tab description");
WTab may have accessible text applied as information additional to the opener's visible content. This additional labelling text may be used to provide better context to users who may not be able to obtain tab context by site. This should be used with care and restraint as it may result in less accessible applications.
// given WTab `tab`
tab.setAccessibleText("Some further context to this tab.");
A WLabel for a WTextField may be given an access key to provide rapid keyboard access. A WTab may have an access key set using the appropriate constructor or using a setter.
// Fiven WTabSet `tabset`
// create a tab with
// - content `contentComponent`
// - opener label "Settings" and
// - accesskey `T`
WTab tab = tabset.addTab(contentComponent, "Settings", 'T');
// with WTab anotherTab
// set the accesskey to 'H'
anotherTab.setAccessKey('H');
It should be noted that access keys are controversial and may even reduce the accessibility of an interface. See Using access keys for more information.
If a WTab contains mandatory fields is not open then the user may not be aware that the tab contains required fields. This can lead to input errors. When a WValidationErrors component is sued to display input errors the fields in closed tabs are not able to be accessed from the error list.
We are not in a position to provide a programmatic solution to this as it is a serious design flaw: under no circumstances should mandatory components, or components with other input restrictions, be placed inside tabs. See WTabSet for more information regarding potential usability issues with tabset and some suggestions of scenarios where tabsets may be useful.
The open state of a WTab is usually determined programmatically based on user interaction but may be set on an instance of WTabSet.
The open state of a given instance of a WTab may be determined using the getter isOpen()
.
// is WTab `tab` open?
boolean tabOpen = tab.isOpen();
A WTab may be disabled on page load. When disabled the WTab will not respond to user input or interaction. A disabled WTab may not be opened. If it is open on page load and in an accordion then the WTab may not be closed. A WTab will also be disabled if its WTabSet is disabled.
Interactive components in the content of a disabled WTab are not automatically disabled.
A WTab may be hidden on page load. When hidden the WTab is not available to any compliant user agent. It is present in the source and is not obscured in any way. This property is determined by a WSubordinateControl. When a WTab is hidden all of its content is hidden.
Setting the hidden property hides the tab opener button and its content. The availability of the content is determined by the open property.
The tab opener is a div element. Before WComponents 1.2 the tab opener was a HTML button element. This placed restrictions on what content may be added to the WTab's opener component.
The following rules are mandatory for a tab opener control:
- the content must include palpable content;
- the content must include content which is available to assistive technologies, for example if the tab's WDecoratedLabel contains only an image then that image must have an appropriate 'alt' attribute which indicates the intent and purpose of the tab controller;
- the content must contain only phrasing content which precludes all WComponents which output non-phrasing content (this will change in release 1.2 to allow flow content);
- the content may not contain any interactive content or labels (this will change in release 1.2 but it is strongly recommended that a tab should not include interactive content as this may cause unexpected event propagation or reduced usability).
The tab content is output inside a div element and is, therefore, able to accept any other components (except, of course, another WApplication or HTML form). It is possible to nest WTabSets but this may cause usability problems. If a UI requires nested WTabSets there may be a problem with the UI design.
The following are tab interactions which have been proposed but are not yet implemented:
- Re-ordering tabs in the client;
- Adding and removing tabs in the client.
Drag-and-drop re-ordering must be keyboard driveable and adding/removing must use the key combinations specified in the WAI-ARIA authoring practices:.
If anyone wants to take one or other of these on raise an enhancement issue and go for it!