--- title: Field Components order: 4 layout: page --- [[components.fields]] = Field Components ((("[classname]#Field#", id="term.components.fields", range="startofrange"))) _Fields_ are components that have a value that the user can change through the user interface. <> illustrates the inheritance relationships and the important interfaces and base classes. [[figure.components.fields]] .Field components image::img/field-diagram-hi.png[width=80%, scaledwidth=100%] Field components are built upon the framework defined in the [classname]#Field# interface and the [classname]#AbstractField# base class. [classname]#AbstractField# is the base class for all field components. In addition to the component features inherited from [classname]#AbstractComponent#, it implements the features defined in the [classname]#HasValue# and [classname]#Component.Focusable# interfaces. [[figure.components.fields.hasvalue]] .Field components having values image::img/field-interface-v8-hi.png[width=60%, scaledwidth=100%] ///////////////////////////////////////////////////////////////////////////// // Disabled because everything has changed in Vaadin 8. // Revise ///////////////////////////////////////////////////////////////////////////// ifdef::disabled[] The description of the field interfaces and base classes is broken down in the following sections. [[components.fields.field]] == The [classname]#Field# Interface The [classname]#Field# interface inherits the [classname]#Component# superinterface and also the [classname]#HasValue# interface to have a value for the field. [classname]#AbstractField# is the only class implementing the [classname]#Field# interface directly. The relationships are illustrated in <>. [[figure.components.fields.field]] .[classname]#Field# interface inheritance image::img/field-interface-hi.png[width=60%, scaledwidth=100%] You can set the field value with the [methodname]#setValue()# and read with the [methodname]#getValue()# method defined in the [classname]#HasValue# interface. The actual value type depends on the component. The [classname]#Field# interface defines a number of properties, which you can access with the corresponding setters and getters. [methodname]#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 [methodname]#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. [methodname]#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. [[components.fields.databinding]] == Data Binding and Conversions Fields and selects can be coupled with business data objects with the [classname]#Binder# class. Select components also allow management of the selectable items through the [classname]#DataSource# interface. [classname]#Binder# and [classname]#DataSource# can be thought of as bridges between the __presentation__ and __model__ architectural layers. Fields are __editors__ for values of some particular type. For example, [classname]#TextField# allows editing [classname]#String# values. When bound to a data source, the type of the source property can be something different, say an [classname]#Integer#. __Converters__ are used for converting the values between the presentation and the model. They are described in <>. [[components.fields.valuechanges]] == Handling Field Value Changes [classname]#Field# inherits [classname]#Property.ValueChangeListener# to allow listening for field value changes and [classname]#Property.Editor# to allow editing values. When the value of a field changes, a [classname]#Property.ValueChangeEvent# is triggered for the field. You should not implement the [methodname]#valueChange()# method in a class inheriting [classname]#AbstractField#, as it is already implemented in [classname]#AbstractField#. You should instead implement the method explicitly by adding the implementing object as a listener. [[components.fields.buffering]] == Field Buffering Field components implement the [interfacename]#Buffered# and [interfacename]#BufferedValidatable# interfaces. When buffering is enabled for a field with [methodname]#setBuffered(true)#, the value is not written to the property data source before the [methodname]#commit()# method is called for the field. Calling [methodname]#commit()# also runs validators added to the field, and if any fail (and the [parameter]#invalidCommitted# is disabled), the value is not written. [source, java] ---- form.addComponent(new Button("Commit", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { try { editor.commit(); } catch (InvalidValueException e) { Notification.show(e.getMessage()); } } })); ---- See the http://demo.vaadin.com/book-examples-vaadin7/book#component.field.buffering.basic[on-line example, window="_blank"]. Calling [methodname]#discard()# reads the value from the property data source to the current input. If the fields are bound in a [classname]#FieldGroup# that has buffering enabled, calling [methodname]#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 <>. [[components.fields.validation]] == Field Validation The input for a field component can be syntactically or semantically invalid. Fields implement the [interfacename]#Validatable# interface, which allows checking validity of the input with __validators__ that implement the [interfacename]#Validator# interface. You can add validators to fields with [methodname]#addValidator()#. [source, java] ---- 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); ---- See the http://demo.vaadin.com/book-examples-vaadin7/book#component.field.validation.basic[on-line example, window="_blank"]. Failed validation is indicated with the error indicator of the field, described in <>, unless disabled with [methodname]#setValidationVisible(false)#. Hovering mouse on the field displays the error message given as a parameter for the validator. If validated explicitly with [methodname]#validate()#, as described later, the [classname]#InvalidValueException# is thrown if the validation fails, also carrying the error message. The value [literal]#++{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 [classname]#IntegerRangeValidator# requires that the value type of the property data source is [classname]#Integer#. [[components.fields.validation.builtin]] === Built-in Validators Vaadin includes the following built-in validators. The property value type is indicated. [classname]#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 [classname]#BeanFieldGroup#. Using bean validation requires an implementation library of the API. See <> for details. [classname]#CompositeValidator#:: Combines validators using logical AND and OR operators. [classname]#DateRangeValidator#: [classname]#Date#:: Checks that the date value is within the range at or between two given dates/times. [classname]#DoubleRangeValidator#: [classname]#Double#:: Checks that the double value is at or between two given values. [classname]#EmailValidator#: [classname]#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. [classname]#IntegerRangeValidator#: [classname]#Integer#:: Checks that the integer value is at or between two given values. [classname]#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 [classname]#TextField#, inputting null values can be enabled with [methodname]#setNullSettingAllowed()#. You also need to set the representation of null values: in selection components with [methodname]#setNullSelectionItemId()# and in [classname]#TextField# with [methodname]#setNullRepresentation()#. ifdef::web[] + Setting field as __required__ can be used for similar effect, and it also enables an indicator to indicate that a value is required. endif::web[] [classname]#RegexpValidator#: [classname]#String#:: Checks that the value matches with the given regular expression. [classname]#StringLengthValidator#: [classname]#String#:: Checks that the length of the input string is at or between two given lengths. ifdef::web[] + The [parameter]#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 [methodname]#setNullSettingAllowed(true)#, and typically in such case, you want to set the null representation to empty string with [methodname]#setNullRepresentation("")#. Note that _this parameter is deprecated_ and should normally be [parameter]#true#; then you can use [methodname]#setRequired()# (for the false case) or [classname]#NullValidator#. endif::web[] Please see the API documentation for more details. [[components.fields.validation.automatic]] === Automatic Validation The validators are normally, when [literal]#++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. [source, java] ---- 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); ---- See the http://demo.vaadin.com/book-examples-vaadin7/book#component.field.validation.basic[on-line example, window="_blank"]. [[components.fields.validation.explicit]] === Explicit Validation The validators are executed when the [methodname]#validate()# or [methodname]#commit()# methods are called for the field. [source, java] ---- // 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); ---- See the http://demo.vaadin.com/book-examples-vaadin7/book#component.field.validation.explicit[on-line example, window="_blank"]. [[components.fields.validation.custom]] === Implementing a Custom Validator You can create custom validators by implementing the [interfacename]#Validator# interface and implementing its [methodname]#validate()# method. If the validation fails, the method should throw either [classname]#InvalidValueException# or [classname]#EmptyValueException#. [source, java] ---- 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); ---- See the http://demo.vaadin.com/book-examples-vaadin7/book#component.field.validation.customvalidator[on-line example, window="_blank"]. [[components.fields.validation.fieldgroup]] === Validation in Field Groups If the field is bound to a [classname]#FieldGroup#, described in <>, calling [methodname]#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. endif::disabled[] (((range="endofrange", startref="term.components.fields")))