Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

components-fields.asciidoc 8.7KB

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