Skip to content

WTextArea

Mark Reeves edited this page Jan 3, 2018 · 23 revisions

WTextArea is a component for creating a multi-line text input field. It has an option to use a rich-text (actually HTML) input which for convenience we will refer to as "rich-text mode".

Why use WTextArea

For most purposes WTextArea is a simple multi-line text input control. It has options to set upper and lower limits on the content entered into it along with default validation rules. The content entered in to WTextArea retains its white-space, unlike WTextField for example.

A WTextArea may also be used to obtain rich-text input as HTML.

Creating a WTextArea

WTextArea has a simple constructor.

WTextArea textarea = new WTextArea();

WTextArea must always be labelled in an accessible manner. This is easiest to do by adding the WTextArea to a WField.

// given WFieldLayout layout and WTextArea textarea
layout.addField("Enter details", textarea);
// ...
// alternately the label for the WTextArea could be a WLabel
WLabel taLabel = new WLabel(LABEL_STRING, textarea);
// ...
// or the WLabel may not be explicitly associated with the WTextArea
// if both are being added via WFieldLayout
taLabel = new WLabel(LABEL_STRING);
// ...
layout.addField(taLabel, textarea);

For more information about alternative ways to ensure a WTextArea is accessible see Labeling a WTextArea.

Using Rich Text

WTextArea has an option to output a rich-text (actually HTML) input using tinyMCE.

WTextArea taRichText = new WTextArea();
// turn on rich-text
taRichText.setRichTextArea(true);

When in rich text mode any input from the user is sanitized using HtmlSanitizerUtil and a rather strict default policy.

When in a read only state the WTextArea outputs unescaped XHTML as part of its payload. To provide a performant mechanism to improve output safety WTextArea provides a mechanism to use HtmlSanitizerUtil to sanitize content in the output stream. For more details see HtmlSanitizerUtil. The default for sanitization was changed from false to true in v1.4.

WTextArea taRichText = new WTextArea();
// turn on rich-text
taRichText.setRichTextArea(true);

// Turns off output sanitization. This may be considered harmful.
taRichText.setSanitizeOnOutput(false);

Setting value

The value of a WTextArea is retained from user input during a session. A default or initial value may be set from a data source or manually.

Set text value

// with WTextArea `field`
field.setText("Some text");

Set data value

// with WTextArea `field` and a data object `obj`
field.setData(obj);

Accessibility

Labeling a WTextArea

All WTextAreas in a UI must be associated with a label or otherwise have their usage and intent exposed to all users. This may be done using (in order of preference):

  • WLabel or by using the WTextArea in a WFieldLayout (preferred) this is required if the label must be visible in the UI; or
  • using the toolTip property if the label does not have to be visible in the UI; or
  • using the accessibleText property.

When designing a UI containing a WTextArea and a visible label the WLabel must be placed immediately before the WTextArea. This is done automatically by WField.

A WTextArea which is not appropriately labelled may display an unlabelled control warning.

Exposing constraints

If the WTextArea has input constraints then there must be an indication of these constraints somewhere in the UI and available to all users. The appropriate place for this information is in the WLabel hint.

If the control is mandatory this indication is automatically generated within the legend element and the legend (if visible) and pseudo-label (if present) are both decorated accordingly.

Setting a toolTip

See toolTip. A WTextArea may use the toolTip property if it is not possible to include a label in the UI. This should be a last resort.

// with WTextArea `field`
field.setToolTip("Some further context to this input.");

Additional labelling text

WTextArea may have accessible text applied as information additional to the visible label text. This should be used with care and restraint as it may result in less accessible applications.

// with WTextArea `field`
field.setAccessibleText("Some further context to this input.");

Access Keys

A WLabel for a WTextArea may be given an access key to provide rapid keyboard access.

Default focus

A WTextArea in an enabled, interactive state may be set as the default focus point for a page. If this is specified it must comply with accessibility principles regarding focus and not put users into a position where they may skip content required for full understanding of the current view.

This property will probably be ignored if the WTextArea is in rich text mode. A WTextArea in a read only state must not be set as the default focus point as it will not be focusable.

See Setting focus for more information.

User override of width and height

Most modern browsers allow the user to resize textarea elements. This size is not retained between page loads and is a convenience for users. It is not able to be disabled in WTextArea as it is considered an accessibillity feature of textarea.

Input constraints

The input allowed in WTextArea may be constrained in several ways.

Mandatory

A WTextArea may be marked as being a mandatory field in the UI. Its accessors are setMandatory(boolean) and getMandatory(). The textarea component of the WTextArea has the required attribute set and any WLabel for the component is decorated with a visual indicator that the component is mandatory. If the WTextArea does not have a placeholder set then it will have a default placeholder (this defaults to the word "required").

// given WTextArea `field`
// make the field mandatory
field.setMandatory(true);

Maximum length

A WTextArea may be constrained to accept a maximum number of input characters. This is based on characters, not on bytes, and is character set dependent.

A user may enter more than the maxLength number of characters, unlike WTextField. This is to allow users to enter or paste a large amount of text (possibly from an existing, external source) and then edit it down to fit.

This property is ignored if the WTextArea is in a read only state.

// given WTextArea `field`
// set the maximum input length to 1000 chars
field.setMaxLength(1000);
The characters remaining ticker

The characters remaining ticker is a usability enhancement for text-mode WTextArea with maxLength set. It provides the user with feedback of how many characters remain within the allowed maxLength. This is a guide only as it reports keyboard characters and does not take into account any keyboard character in the content which may be HTML escaped (such as < or &). When the user has entered more than maxLength characters the counter will display a negative number and the WTextArea may be placed in an invalid state but the user will still be able to enter further text.

The characters remaining ticker is incompatible with rich text mode.

example WTextArea showing characters remaining

Minimum length

WTextArea may be constrained to accept a minimum number of characters which will be considered acceptable input if any input is added at all. This is based on characters, not on bytes, and is character set dependent.

This property is ignored if the WTextArea is in a read only state.

// given WTextArea `field`
// set the minimum input length to 10 chars
field.setMinLength(10);

Setting a minimum length will not automatically make the WTextArea mandatory. The minimum length is validated only if the WTextArea has user input. To make a WTextArea mandatory use mandatory. These properties may be used in conjunction to enforce a required minimum content input by the user.

// given WTextArea `field`
// set the minimum input length to 10 chars
field.setMinLength(10);
field.setMandatory(true);

Appearance

WTextArea will output a standard HTML textarea element and its appearance is determined by the user agent. When in rich text mode the appearance is determined by tinyMCE.

example WTextArea

Setting height

The vertical size of the HTML textarea is set using the rows property.

// given WTextArea `field`
field.setRows(10);

example WTextArea with rows set

If this property is not specified the height of the textarea will be determined by the user agent.

This property is ignored if the WTextArea is in a read only state or in rich text mode.

Setting width

The width of a WTextArea's input control (when not in rich text mode) may be set using the cols property, by CSS or by using WField setInputWidth(int).

It is, of course, possible to restrain textarea width using CSS in either a theme implementation or as custom CSS.

Wherever possible a WTextArea will be constrained to be no wider than its containing element.

Width in columns

The number of 'columns' to display may be set on a WTextArea. This is used to set the vertical size of the HTML textarea to this number of visible 'columns'. This is not implemented in rich text mode.

// given WTextArea field
field.setCols(40);

Whilst seemingly analogous to the WTextField size property user-agents use fundamentally different techniques to calculate the size of the replaced UI widget for both of these element types and they are not the same. A WTextField with a size of 30, for example, will not necessarily be the same width as a WTextArea with a cols of 30.

If this property is not specified the width of the textarea will be determined by the user agent. The maximum width of a WTextArea is determined by its containing element but may be overridden by the cols property if the containing element has automatic width (such as a cell in a horizontal FlowLayout).

Setting cols may result in the textarea not being able to be resized to fit its container on small viewports. In may cases it may be more appropriate to use WField setInputWidth(int) to control the width of a WTextArea.

example WTextArea with cols set

This property is ignored if the WTextArea is in a read only state or in rich text mode.

Customising based on HTML class

WTextArea may have one or more values to be added to the component's wrapper element. This can be used for fine-grain styling of specific components but should be used with care.

For more information see WComponents HTML class property.

The values added using this property will probably be ignored if the WTextArea is in rich text mode.

HTML output

When interactive but not in rich text mode a WTextArea will output a span wrapping a textarea element (and optionally a output element). This textarea element is an interactive, form bound control and therefore may not be used in any context where the content model forbids this content category.

If the WTextArea is in rich text mode it will output an application which includes non-phrasing content and form-bound content and therefore may not be used in any context where the content model forbids this content category. The Rich-text control is implemented using tinyMCE.

When in read-only mode a rich-text WTextArea will output a div element and the HTML content of that WTextArea. The HTML content is not escaped but may be sanitized.

example WTextArea in read-only mode

Change action

A WTextArea may be used to trigger an Action which runs if the field's value changes. This will trigger any time the value changes and the server application is informed, not only if the WTextArea triggers the call back to the server by being a trigger for a WAjaxControl.

// with WTextArea `field`
field.setActionOnChange(new Action() {
  @Override
  public void execute(final ActionEvent event) {
    // do something
  }
});

Rich text mode

This is used to indicate that the WTextArea should provide a means for the user to input HTML content. The default implementation uses tinyMCE. The global tinyMCE configuration is set in theme JavaScript and individual instances of WTextArea may have their own configuration.

example rich-text mode WTextArea

Setting a tinyMCE configuration

Configuration of tinyMCE should be as per their documentation but needs to be applied to WTextArea using WComponents' JavaScript configuration module wc/config.

require(["wc/config"], function (wcconfig) {
  var configObj;
  // set up configuration object `configObj`
  // eg as a tinyMCE init object
  configObj = {
    menubar: 'file edit insert view format table tools',
    remove_trailing_brs: true
  };
  // then set the configuration into `wc/ui/rtf` with the tinyMCE init
  // object assigned to the member `initObj`:
  wcconfig.set({initObj: configObj}, "wc/ui/rtf");});

Read only

The read-only state changes the output rendering of the WTextArea but this output is also altered by the rich text mode:

  • when in text mode the output is a span elementwhich holds simple text and may retain white-space in the content;

    example text mode WTextArea in read-only mode

  • when in rich text mode the output is a HTML div element which holds the HTML equivalent (possibly sanitized) of the WTextArea content.

    example rich-text mode WTextArea in read-only mode

A WTextArea in a read only state may be the target of a WSubordinateControl or WAjaxControl. If it is the target of an AJAX action its read-only state may be changed.

// given WTextArea `field`
field.setReadOnly(true);

Disabling

A WTextArea may be disabled on page load. When disabled the WTextArea will not respond to user input or interaction.

This property may be used in conjunction with WSubordinateControl controls to enable or disable content without making another server call.

This property is ignored if the WTextArea is in a read only state.

// given WTextArea `field`
// make it disabled
field.setDisabled(true);

Hiding

A WTextArea may be hidden on page load. When hidden the WTextArea 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 WTextArea is hidden any WLabel associated with it is also hidden.

This property is ignored if the WTextArea is in a read only state.

Placeholder

WTextArea may have a "placeholder" in an empty instance of an editable WTextArea which is not set to receive rich-text.

One should note that the placeholder is

  • not visible in all browsers;
  • is not visible if the WTextArea contains any input; and
  • must not be used as a replacement for a label.
// given WTextArea `field`
// to set the placeholder
field.setPlaceholder("type here");

This property is ignored if the WTextArea is in a read only state.

Testing

WTextArea may be tested using the com.github.bordertech.wcomponents.test.selenium.element.SeleniumWTextAreaWebElement extension of org.openqa.selenium.WebElement.

The best way to get a WTextArea from a test view is by using SeleniumWComponentsWebDriver which has a method findWTextArea(By). This can be used in conjunction with com.github.bordertech.wcomponents.test.selenium.ByLabel, for example, to find a WTextArea using its label's text.

@Test
public void testFindByLabel() {
  SeleniumWComponentsWebDriver driver = getDriver();
  String labelText = "Provide details";
  SeleniumWTextAreaWebElement field =
    driver.findWTextArea(new ByLabel(labelText, false));
  Assert.assertNotNull("Unable to find textarea by label text", field);
}

For more information on members provided by SeleniumWTextAreaWebElement see:

From v1.4 onwards SeleniumWTextAreaWebElement also provides:

  • int getMaxLength()

    @Test
    public void testMaxLength() {
      SeleniumWComponentsWebDriver driver = getDriver();
      String labelText = "Provide details";
      int expected = "200";
      SeleniumWTextAreaWebElement field =
        driver.findWTextArea(new ByLabel(labelText, false));
      Assert.assertEquals("did not get expected maxLength attribute",
        expected, field.getMaxLength());
    }
  • void clearContent() to remove all content from the WTextArea which may be useful for testing sendKeys, setContent etc.

    // assume a WTextArea with existing (unknown) text content:
    @Test
    public void clearContent() {
      SeleniumWComponentsWebDriver driver = getDriver();
      String labelText = "Pre-set details";
      SeleniumWTextAreaWebElement field =
        driver.findWTextArea(new ByLabel(labelText, false));
      // precondition: the field is known to not be empty
      Assert.assertNotEquals("Field should not be empty", "", field.getValue());
      field.clearContent();
      Assert.assertEquals("Field should be empty", "", field.getValue());
      // one may then use sendKeys to set new content.
    }

Known errors

In v1.3 and before the override of boolean isReadOnly() in SeleniumWTextAreaWebElement will provide a false negative if the WTextArea is in rich text mode.

Related components

Further information

Clone this wiki locally