Field Components

Fields are components that have a value that the user can change through the user interface. Field components illustrates the inheritance relationships and the important interfaces and base classes.

Field components

Field components are built upon the framework defined in the Field interface and the AbstractField base class. AbstractField is the base class for all field components. In addition to the component features inherited from AbstractComponent, it implements a number of features defined in Property, Buffered, Validatable, and Component.Focusable interfaces.

The description of the field interfaces and base classes is broken down in the following sections.

The Field Interface

The Field interface inherits the Component superinterface and also the Property interface to have a value for the field. AbstractField is the only class implementing the Field interface directly. The relationships are illustrated in Field interface inheritance.

Field interface inheritance

You can set the field value with the setValue() and read with the getValue() method defined in the Property interface. The actual value type depends on the component.

The Field interface defines a number of properties, which you can access with the corresponding setters and getters.

required

When enabled, a required indicator (usually the asterisk * character) is displayed on the left, above, or right the field, depending on the containing layout and whether the field has a caption. If such fields are validated but are empty and the requiredError property (see below) is set, an error indicator is shown and the component error is set to the text defined with the error property. Without validation, the required indicator is merely a visual guide.

requiredError

Defines the error message to show when a value is required, but none is entered. The error message is set as the component error for the field and is usually displayed in a tooltip when the mouse pointer hovers over the error indicator.

Data Binding and Conversions

Fields are strongly coupled with the Vaadin data model. The field value is handled as a Property of the field component, as documented in "Properties". Selection fields allow management of the selectable items through the Container interface.

Fields are editors for some particular type. For example, TextField allows editing String values. When bound to a data source, the property type of the data model can be something different, say an Integer. Converters are used for converting the values between the representation and the model. They are described in "Converting Between Property Type and Representation".

Handling Field Value Changes

Field inherits Property.ValueChangeListener to allow listening for field value changes and Property.Editor to allow editing values.

When the value of a field changes, a Property.ValueChangeEvent is triggered for the field. You should not implement the valueChange() method in a class inheriting AbstractField, as it is already implemented in AbstractField. You should instead implement the method explicitly by adding the implementing object as a listener.

Field Buffering

Field components implement the Buffered and BufferedValidatable interfaces. When buffering is enabled for a field with setBuffered(true), the value is not written to the property data source before the commit() method is called for the field. Calling commit() also runs validators added to the field, and if any fail (and the invalidCommitted is disabled), the value is not written.

form.addComponent(new Button("Commit",
    new Button.ClickListener() {
    @Override
    public void buttonClick(ClickEvent event) {
        try {
            editor.commit();
        } catch (InvalidValueException e) {
            Notification.show(e.getMessage());
        }
    }
}));

Calling discard() reads the value from the property data source to the current input.

If the fields are bound in a FieldGroup that has buffering enabled, calling commit() for the group runs validation on all fields in the group, and if successful, all the field values are written to the item data source. See "Buffering Forms".

Field Validation

The input for a field component can be syntactically or semantically invalid. Fields implement the Validatable interface, which allows checking validity of the input with validators that implement the Validator interface. You can add validators to fields with addValidator().

TextField field = new TextField("Name");
field.addValidator(new StringLengthValidator(
    "The name must be 1-10 letters (was {0})",
    1, 10, true));
field.setNullRepresentation("");
field.setNullSettingAllowed(true);
layout.addComponent(field);

Failed validation is indicated with the error indicator of the field, described in "Error Indicator and Message", unless disabled with setValidationVisible(false). Hovering mouse on the field displays the error message given as a parameter for the validator. If validated explicitly with validate(), as described later, the InvalidValueException is thrown if the validation fails, also carrying the error message. The value {0} in the error message string is replaced with the invalid input value.

Validators validate the property type of the field after a possible conversion, not the presentation type. For example, an IntegerRangeValidator requires that the value type of the property data source is Integer.

Built-in Validators

Vaadin includes the following built-in validators. The property value type is indicated.

BeanValidator

Validates a bean property according to annotations defined in the Bean Validation API 1.0 (JSR-303). This validator is usually not used explicitly, but they are created implicitly when binding fields in a BeanFieldGroup. Using bean validation requires an implementation library of the API. See "Bean Validation" for details.

CompositeValidator

Combines validators using logical AND and OR operators.

DateRangeValidator: Date

Checks that the date value is within the range at or between two given dates/times.

DoubleRangeValidator: Double

Checks that the double value is at or between two given values.

EmailValidator: String

Checks that the string value is a syntactically valid email address. The validated syntax is close to the RFC 822 standard regarding email addresses.

IntegerRangeValidator: Integer

Checks that the integer value is at or between two given values.

NullValidator

Checks whether the value is or is not a null value.

For the validator to be meaningful, the component must support inputting null values. For example, for selection components and TextField, inputting null values can be enabled with setNullSettingAllowed(). You also need to set the representation of null values: in selection components with setNullSelectionItemId() and in TextField with setNullRepresentation().

Setting field as required can be used for similar effect, and it also enables an indicator to indicate that a value is required.

RegexpValidator: String

Checks that the value matches with the given regular expression.

StringLengthValidator: String

Checks that the length of the input string is at or between two given lengths.

The allowNull parameter determines whether null values should be allowed for the string, regardless of the string length. A null value has zero length, so it will be invalid if the minimum length is greater than zero. Allowing null value is meaningful only if inputting null values is enabled with setNullSettingAllowed(true), and typically in such case, you want to set the null representation to empty string with setNullRepresentation(""). Note that this parameter is deprecated and should normally be true; then you can use setRequired() (for the false case) or NullValidator.

Please see the API documentation for more details.

Automatic Validation

The validators are normally, when validationVisible is true for the field, executed implicitly on the next server request if the input has changed. If the field is in immediate mode, it (and any other fields with changed value) are validated immediately when the focus leaves the field.

TextField field = new TextField("Name");
field.addValidator(new StringLengthValidator(
    "The name must be 1-10 letters (was {0})",
    1, 10, true));
field.setImmediate(true);
field.setNullRepresentation("");
field.setNullSettingAllowed(true);
layout.addComponent(field);

Explicit Validation

The validators are executed when the validate() or commit() methods are called for the field.

// A field with automatic validation disabled
final TextField field = new TextField("Name");
field.setNullRepresentation("");
field.setNullSettingAllowed(true);
layout.addComponent(field);

// Define validation as usual
field.addValidator(new StringLengthValidator(
    "The name must be 1-10 letters (was {0})",
    1, 10, true));

// Run validation explicitly
Button validate = new Button("Validate");
validate.addClickListener(new ClickListener() {
    @Override
    public void buttonClick(ClickEvent event) {
        field.setValidationVisible(false);
        try {
            field.validate();
        } catch (InvalidValueException e) {
            Notification.show(e.getMessage());
            field.setValidationVisible(true);
        }
    }
});
layout.addComponent(validate);

Implementing a Custom Validator

You can create custom validators by implementing the Validator interface and implementing its validate() method. If the validation fails, the method should throw either InvalidValueException or EmptyValueException.

class MyValidator implements Validator {
    @Override
    public void validate(Object value)
            throws InvalidValueException {
        if (!(value instanceof String &&
                ((String)value).equals("hello")))
            throw new InvalidValueException("You're impolite");
    }
}

TextField field = new TextField("Say hello");
field.addValidator(new MyValidator());
field.setImmediate(true);
layout.addComponent(field);

Validation in Field Groups

If the field is bound to a FieldGroup, described in "Creating Forms by Binding Fields to Items", calling commit() for the group runs the validation for all the fields in the group, and if successful, writes the input values to the data source.