You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

components-fields.asciidoc 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. ---
  2. title: Field Components
  3. order: 4
  4. layout: page
  5. ---
  6. [[components.fields]]
  7. = Field Components
  8. ((("[classname]#Field#", id="term.components.fields", range="startofrange")))
  9. _Fields_ are components that have a value that the user can change through the
  10. user interface. <<figure.components.fields>> illustrates the inheritance relationships
  11. and the important interfaces and base classes.
  12. [[figure.components.fields]]
  13. .Field components
  14. image::img/field-diagram-hi.png[width=80%, scaledwidth=100%]
  15. Field components are built upon the framework defined in the [classname]#Field#
  16. interface and the [classname]#AbstractField# base class.
  17. [classname]#AbstractField# is the base class for all field components. In
  18. addition to the component features inherited from
  19. [classname]#AbstractComponent#, it implements the features defined in the
  20. [classname]#HasValue# and [classname]#Component.Focusable# interfaces.
  21. [[figure.components.fields.hasvalue]]
  22. .Field components having values
  23. image::img/field-interface-v8-hi.png[width=60%, scaledwidth=100%]
  24. The description of the field interfaces and base classes is broken down in the
  25. following sections.
  26. [[components.fields.field]]
  27. == The [classname]#Field# Interface
  28. The [classname]#Field# interface inherits the [classname]#Component#
  29. superinterface and also the [classname]#HasValue# interface to have a value for
  30. the field. [classname]#AbstractField# is the only class implementing the
  31. [classname]#Field# interface directly. The relationships are illustrated in
  32. <<figure.components.fields.field>>.
  33. [[figure.components.fields.field]]
  34. .[classname]#Field# interface inheritance
  35. image::img/field-interface-hi.png[width=60%, scaledwidth=100%]
  36. You can set the field value with the [methodname]#setValue()# and read with the
  37. [methodname]#getValue()# method defined in the [classname]#HasValue# interface.
  38. The actual value type depends on the component.
  39. The [classname]#Field# interface defines a number of properties, which you can
  40. access with the corresponding setters and getters.
  41. [methodname]#required#:: When enabled, a required indicator (usually the asterisk * character) is
  42. displayed on the left, above, or right the field, depending on the containing
  43. layout and whether the field has a caption. If such fields are validated but are
  44. empty and the [methodname]#requiredError# property (see below) is set, an error
  45. indicator is shown and the component error is set to the text defined with the
  46. error property. Without validation, the required indicator is merely a visual
  47. guide.
  48. [methodname]#requiredError#:: Defines the error message to show when a value is required, but none is entered.
  49. The error message is set as the component error for the field and is usually
  50. displayed in a tooltip when the mouse pointer hovers over the error indicator.
  51. [[components.fields.valuechanges]]
  52. == Handling Field Value Changes
  53. [classname]#Field# provides two methods for listening to changes to the field value:
  54. [methodname]#onChange# and [methodname]#addValueChangeListener#. The difference
  55. is that the former takes a [interfacename]#Consumer# object that only receives the new value;
  56. the latter, on the other hand, takes an [interfacename]#EventListener# that gets
  57. a [classname]#ValueChange# event instance containing extra information about the event.
  58. Both methods return a [classname]#Registration# object that can be used to later
  59. remove the added listener if necessary.
  60. [source, java]
  61. ----
  62. TextField textField = new TextField();
  63. Label echo = new Label();
  64. // Just echo in the label anything the user enters
  65. textField.onChange(echo::setValue);
  66. // Add a more complex listener
  67. textField.addValueChangeListener(event -> {
  68. String origin = event.isUserOriginated()
  69. ? "user"
  70. : "application";
  71. String message = origin
  72. + " entered the following: "
  73. + event.getValue();
  74. Notification.show(message);
  75. });
  76. ----
  77. [[components.fields.databinding]]
  78. == Binding Fields to Data
  79. Fields can be grouped into _forms_ and coupled with business data objects with
  80. the [classname]#Binder# class. When a field is bound to a property using
  81. [classname]#Binder#, it gets its default value from the property, and
  82. is stored to the property either manually via the [methodname]#Binder.save# method,
  83. or automatically every time the value changes.
  84. [source, java]
  85. ----
  86. class Person {
  87. private String name;
  88. public String getName() { /* ... */ }
  89. public void setName(String) { /* ... */ }
  90. }
  91. TextField nameField = new TextField();
  92. Binder<Person> binder = new Binder<>();
  93. // Bind nameField to the Person.name property
  94. // by specifying its getter and setter
  95. binder.forField(nameField)
  96. .bind(Person::getName, Person::setName);
  97. // Bind an actual concrete Person instance.
  98. // After this, whenever the user changes the value
  99. // of nameField, p.setName is automatically called.
  100. Person p = new Person();
  101. binder.bind(p;
  102. ----
  103. == Validating Field Values
  104. User input may be syntactically or semantically invalid.
  105. [classname]#Binder# allows adding a chain of one or more __validators__ for
  106. automatically checking the validity of the input before storing it to the data
  107. object. You can add validators to fields by calling the [methodname]#withValidator#
  108. method on the [interfacename]#Binding# object returned by [methodname]#Binder.forField#.
  109. [source, java]
  110. ----
  111. binder.forField(nameField)
  112. .withValidator(new StringLengthValidator(2, 20,
  113. "Name must be between 2 and 20 characters long"))
  114. .bind(Person::getName, Person::setName);
  115. ----
  116. Failed validation is indicated with the error indicator of the field, described in
  117. <<dummy/../../../framework/application/application-errors#application.errors.error-indicator,"Error
  118. Indicator and Message">>. Hovering mouse on the field displays the error message
  119. returned by the validator. If any value in a set of bound fields fails validation,
  120. none of the field values are saved into the bound property until the validation
  121. passes.
  122. [[components.fields.validation.builtin]]
  123. === Built-in Validators
  124. Vaadin includes the following built-in validators. The property value type is
  125. indicated.
  126. [classname]#RangeValidator#: [classname]#Comparable#::
  127. Checks that the given [interfacename]#Comparable# value is at or between two given values.
  128. [classname]#StringLengthValidator#: [classname]#String#::
  129. Checks that the length of the input string is at or between two given lengths.
  130. [classname]#RegexpValidator#: [classname]#String#::
  131. Checks that the value matches the given regular expression.
  132. [classname]#EmailValidator#: [classname]#String#::
  133. Checks that the string value is a syntactically valid email address.
  134. The validated syntax is close to the RFC 822 standard regarding email addresses.
  135. === Implementing Custom Validators
  136. Validators implement the [interfacename]#Validator# interface that simply
  137. extends [interfacename]#java.util.function.Function#, returning a special type
  138. called [interfacename]#Result#. This return type represents the validation outcome:
  139. whether or not the given input was valid.
  140. [source, java]
  141. ----
  142. class MyValidator implements Validator<String> {
  143. @Override
  144. public Result<String> apply(String input) {
  145. if(input.length() == 6) {
  146. return Result.ok(input);
  147. } else {
  148. return Result.error(
  149. "Must be exactly six characters long");
  150. }
  151. }
  152. }
  153. ----
  154. Because [methodname]#Result.ok# takes the valid value as an argument, a validator
  155. can also do some sanitization on valid inputs, such as removing leading and
  156. trailing whitespace from a string. Since [interfacename]#Validator# is a functional
  157. interface, you can often simply write a lambda expression instead of a full class
  158. declaration. There is also an [methodname]#withValidator# overload that creates a
  159. validator from a boolean function and an error message.
  160. [source, java]
  161. ----
  162. binder.forField(nameField)
  163. .withValidator(name -> name.length() < 20,
  164. "Name must be less than 20 characters long")
  165. .bind(Person::getName, Person::setName);
  166. ----
  167. == Converting Field Values
  168. Field values are always of some particular type. For example,
  169. [classname]#TextField# allows editing [classname]#String# values. When bound to
  170. a data source, the type of the source property can be something different,
  171. say an [classname]#Integer#. __Converters__ are used for converting the values
  172. between the presentation and the model. Their usage is described in
  173. <<dummy/../../../framework/datamodel/datamodel-properties#datamodel.properties.converter,"Converting
  174. Between Model and Presentation Types">>.
  175. (((range="endofrange", startref="term.components.fields")))