Skip to content

WFieldLayout

Mark Reeves edited this page Mar 21, 2018 · 14 revisions

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

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:

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());

Sample WFields in a WFieldLayout

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.

Naming context

WFieldLayout may be used to create a naming context rather than using a separate WNamingContext.

Creating a WFieldLayout

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);

Adding fields

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.

Accessibility

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".

Example WFieldLayout showing different label positions

// 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);

Choosing an appropriate layout

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:

Comparisons of layouts with a long label

Sample appearance

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.

Sample WFields in a WFieldLayout

Layouts

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.

    Example of a WFieldLayout with layout FLAT

  • LAYOUT_STACKED in which the label is above the form control

    Example of a WFieldLayout with layout STACKED

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.

Theme support

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.

Label control split

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.

Interaction of labelWidth and layout

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.

Example showing the effect of labelWidth

Theme support for labelWidth

If building a WComponents theme the level of support for labelwidth is set using several Sass variables.

  • $wc-fieldlayout-force-stack if set to true 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 is 0 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 to 25, 33 or 50 but any value from 0 to 100 is acceptable.

  • $wc-fld-list is a complex variable which is used to determine which labelWidth values are supported by a theme. The supported options are:

    • if set to the single value -1 then all labelWidth values (from 1 to 100) 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 all labelWidth values which are a multiple of 5 (from 5 to 100) 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 of labelWidth and enforce the theme default.

Hiding

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.

Responsive design

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.

Margins

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.

Related components

Further information

Clone this wiki locally