-
Notifications
You must be signed in to change notification settings - Fork 17
WFieldLayout
WFieldLayout is a component for setting a consistent layout for a group of form controls and their associated labels. When form controls are added to the UI they should almost always be added to a WFieldLayout. WFieldLayout may be the target of a WAjaxControl or WSubordinateControl.
- Why use WFieldLayout
- Creating a WFieldLayout
- Accessibility
- Sample appearance
- Layouts
- Label control split
- Hiding
- Responsive design
- Margins
- Related components
- Further information
WFieldLayout is the primary and recommended tool for adding label:control pairs to a WComponents application.
The main advantage of WFieldLayout is that it is not necessary to:
- know the correct order of labels and inputs; or
- know what type of input control (a simple labelable input or a complex form control); or
- know whether a WComponent is even a data input component.
As an example, to create the layout illustrated below using WFieldLayout and WField one could use Java similar to the following:
WFieldLayout layout = new WFieldLayout();
layout.addField("WTextField 1", new WTextField());
layout.addField("WTextField 2", new WTextField());
layout.addField("WCheckBox", new WCheckBox());
WFieldLayout is a potential target component for both WAjaxControl and WSubordinateControl and is also a Marginable component. It can, therefore, almost always be used as a primary layout component.
WFieldLayout may be used to create a naming context rather than using a separate WNamingContext.
WFieldLayout has a simple constructor and a constructor which can accept a layout.
WFieldLayout layout = new WFieldLayout();
WFieldLayout flatLayout = new WFieldLayout(WFieldLayout.LAYOUT_FLAT);
WFieldLayout stackedLayout = new WFieldLayout(WFieldLayout.LAYOUT_STACKED);
WComponents are added to a WFieldLayout using addField
. There are three overloaded versions of this:
addField(WButton)
addField(String, WComponent)
addField(WLabel, WComponent)
// With WFieldLayout layout
//...
// addField with String label and WTextField givenName
layout.addField("Given name", givenName);
// addField with i18n token (String) FAMILY_NAME & WTextField familyName
layout.addField(FAMILY_NAME, familyName);
// addField with WLabel dobLabel & WDateField dobDate
layout.addField(dobLabel, dobDate);
// addField with WButton saveButton
layout.addField(saveButton);
addField
returns the WField which was added.
WFieldLayout helps with maintaining accessible forms by ensuring an input control, even a complex form control, is labelled in the most appropriate way and when the label is visible in the UI it is in the appropriate position relative to the labelled control. The label:control pairs are added in the same way for all controls and WFieldLayout determines the correct output.
In the illustration below three fields are added to the WFieldLayout. They are added all in the same way and WFieldLayout correctly positions the labels dependent on the labelled component. The required field markers are also positioned variously depending on the location of the "label".
// Set up the form controls somewhere. We can assume they have each
// been initialised and set up appropriately.
// Most simple input have the label before the control.
// WTextField is a typical example of one of these.
WTextField tfQuestion;
// Check boxes and radios have the label after the control.
WCheckBox cbCheck;
WRadioButton radio;
// Complex form controls are output inside a HTML fieldset element
// so the "label" is not a label element at all.
// WRadioButtonSelect is an example of these types of controls.
WRadioButtonSelect rbSelect;
// ...
// Add the controls to WFieldLayout `layout`. Note that the type
// and position of the label relative to the input is not important.
layout.addField("This is a question", tfQuestion);
layout.addField("This is a checkbox", cbCheck);
layout.addField("This is a radio button", radio);
layout.addField("Choose a shape", rbSelect);
As in all things with design the most appropriate layout for a WFieldLayout will be determined by the content — in this case the information architecture of the labels and form control components — and expected use cases including expected platforms (such as small screen mobile devices).
For most purposes the LAYOUT_STACKED
layout should be used. This provides the best combination of ease of use, excellent a11y and responsiveness to small form factor devices.
If your labels are lengthy or you have numerous large multi-line text inputs or other large input controls then LAYOUT_STACKED
will give the cleanest layout. There are significant accessibility arguments in favour of LAYOUT_STACKED
, especially in the area of assisting users with certain cognitive issues.
For simple forms with short labels and small controls then LAYOUT_FLAT
is commonly used. This is a reasonable layout with few significant accessibility barriers. LAYOUT_FLAT
can become unwieldy if the label content is large causing long wrapped labels as is illustrated in the following diagram:
WFieldLayout is itself transparent and is used to arrange labels and input components in a consistent and accessible manner. The illustration shown a sample various WComponents added to a WFieldLayout using WField.
The layout
property determines the visual layout of the form controls and their labels. Available settings for this property are:
-
LAYOUT_FLAT
in which the label is in line with and before the form control. This layout may be ignored by a theme either as part of responsive design or as a global theme choice. -
LAYOUT_STACKED
in which the label is above the form control
Note: In all layouts the label for a radio button or for a check box will be placed in line with and immediately after the form control.
If building a WComponents theme the level of support for layout is set using Sass variables. The vsariables and their default values are listed in src/main/sass/vars/_fieldlayout.scss
.
If the variable $wc-fieldlayout-force-stack
is set to false
(which is the default) then LAYOUT_FLAT
will be supported to some degree in wider viewports. See the labelWidth property and responsive design for more information.
When the layout is LAYOUT_FLAT
the proportion of horizontal space allowed for the label is set by the labelWidth
property. The default value for this is set by the theme implementation and defaults to 50%.
The labelWidth
property is an integer (0-100) and is translated as a percentage of the width of the container element's content box. The labelWidth
is used to ensure that form controls align vertically. If the content of a WLabel exceeds the available width it will wrap. This may cause come issues with labels for some WComponents. This is discussed in detail in WComponents which output form controls.
If the labelWidth
is not specified it will be determined by the theme. If a UI requires a split of any other proportion it must be explicitly stated in the UI specification for all WFieldLayouts.
// Set the label:input proportions to ~ 1:2.
// With WFieldLayout layout:
layout.setLabelWidth(33);
A theme may not support all possible values of labelWidth
. This allows a theme to enforce a common look and feel and reduce the amount of CSS needed to support WFieldLayout.
When the layout is LAYOUT_STACKED
the label for each control may extend across the entire available width of the parent element's content box. In this case the labelWidth
property does not limit this width but does still indent the form controls. This allows a form segment to be predominantly LAYOUT_FLAT
but to have interspersed LAYOUT_STACKED
WFieldLayouts when the content of the WLabel is longer than can be sensibly contained within the labelWidth
.
This diagram shows a LAYOUT_FLAT
WFieldLayout and a LAYOUT_STACKED
WFieldLayout both with the same labelWidth
to illustrate the indentation of the form controls in the LAYOUT_STACKED
WFieldLayout.
If building a WComponents theme the level of support for labelwidth is set using several Sass variables.
-
$wc-fieldlayout-force-stack
if set totrue
will force all WFieldLayouts to appear as LAYOUT_STACKED and no values of labelwidth are honoured. If this is the case all of the following variables are ignored. The default is0
which allows use of LAYOUT_FLAT -
$wc-fieldlayout-default-label-width
is used to set the default labelwidth for LAYOUT_FLAT. This will also be the width used if the labelwidth property is set to any unsupported value. It is recommended this be set to25
,33
or50
but any value from0
to100
is acceptable. -
$wc-fld-list
is a complex variable which is used to determine whichlabelWidth
values are supported by a theme. The supported options are:- if set to the single value
-1
then alllabelWidth
values (from1
to100
) will be supported but at the cost of a lot of CSS and no ability to enforce consistency; - if set to the single value
0
then alllabelWidth
values which are a multiple of 5 (from5
to100
) will be supported with a significant reduction in CSS and more consistency; - if set to a list of integer values (each between 1 and 100) then all
labelWidth
values which are a multiple of 5% will be supported along with the values included in the list.
The implementation of this variable is undergoing an update to separate the list of options from the 5% multiples allowing a theme to support a much smaller set of
labelWidth
values. This update will also allow a theme to ignore all values oflabelWidth
and enforce the theme default. - if set to the single value
A WFieldLayout may be hidden on page load. This property is determined by a WSubordinateControl. When hidden the WFieldLayout is not available to any compliant user agent. It is present in the source and is not obscured in any way.
When the layout is LAYOUT_FLAT but the user has a narrow viewport the WFieldLayout will reflow to have an appearance identical to that of LAYOUT_STACKED with no labelwidth set. The labelwidth property is ignored when the viewport is narrow for both LAYOUT_FLAT and LAYOUT_STACKED layouts. See [Responsive Design] for more information.
WFieldLayout is a marginable component.
In some themes immediate sibling WFieldLayouts are automatically spaced so that the inter-field-layout gap is the same as the theme's intra-field-layout gaps for WFields within the WFieldLayout. This allows a mixture of WFieldLayout layouts without having to use a wrapping FlowLayout and which allows the gap between WFieldLayouts to flex with viewport size if required.