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 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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
  11. relationships and the important interfaces and base classes.
  12. [[figure.components.fields]]
  13. .Field components
  14. image::img/field-diagram-hi.png[width=60%, 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 a number of features defined in
  20. [classname]#Property#, [classname]#Buffered#, [classname]#Validatable#, and
  21. [classname]#Component.Focusable# interfaces.
  22. The description of the field interfaces and base classes is broken down in the
  23. following sections.
  24. [[components.fields.field]]
  25. == The [classname]#Field# Interface
  26. The [classname]#Field# interface inherits the [classname]#Component#
  27. superinterface and also the [classname]#Property# interface to have a value for
  28. the field. [classname]#AbstractField# is the only class implementing the
  29. [classname]#Field# interface directly. The relationships are illustrated in
  30. <<figure.components.fields.field>>.
  31. [[figure.components.fields.field]]
  32. .[classname]#Field# interface inheritance
  33. image::img/field-interface-hi.png[width=60%, scaledwidth=100%]
  34. You can set the field value with the [methodname]#setValue()# and read with the
  35. [methodname]#getValue()# method defined in the [classname]#Property# interface.
  36. The actual value type depends on the component.
  37. The [classname]#Field# interface defines a number of properties, which you can
  38. access with the corresponding setters and getters.
  39. [methodname]#required#:: When enabled, a required indicator (usually the asterisk * character) is
  40. displayed on the left, above, or right the field, depending on the containing
  41. layout and whether the field has a caption. If such fields are validated but are
  42. empty and the [methodname]#requiredError# property (see below) is set, an error
  43. indicator is shown and the component error is set to the text defined with the
  44. error property. Without validation, the required indicator is merely a visual
  45. guide.
  46. [methodname]#requiredError#:: Defines the error message to show when a value is required, but none is entered.
  47. The error message is set as the component error for the field and is usually
  48. displayed in a tooltip when the mouse pointer hovers over the error indicator.
  49. [[components.fields.databinding]]
  50. == Data Binding and Conversions
  51. Fields are strongly coupled with the Vaadin data model. The field value is
  52. handled as a [classname]#Property# of the field component, as documented in
  53. <<dummy/../../../framework/datamodel/datamodel-properties#datamodel.properties,"Properties">>.
  54. Selection fields allow management of the selectable items through the
  55. [classname]#Container# interface.
  56. Fields are __editors__ for some particular type. For example,
  57. [classname]#TextField# allows editing [classname]#String# values. When bound to
  58. a data source, the property type of the data model can be something different,
  59. say an [classname]#Integer#. __Converters__ are used for converting the values
  60. between the representation and the model. They are described in
  61. <<dummy/../../../framework/datamodel/datamodel-properties#datamodel.properties.converter,"Converting
  62. Between Property Type and Representation">>.
  63. [[components.fields.valuechanges]]
  64. == Handling Field Value Changes
  65. [classname]#Field# inherits [classname]#Property.ValueChangeListener# to allow
  66. listening for field value changes and [classname]#Property.Editor# to allow
  67. editing values.
  68. When the value of a field changes, a [classname]#Property.ValueChangeEvent# is
  69. triggered for the field. You should not implement the
  70. [methodname]#valueChange()# method in a class inheriting
  71. [classname]#AbstractField#, as it is already implemented in
  72. [classname]#AbstractField#. You should instead implement the method explicitly
  73. by adding the implementing object as a listener.
  74. [[components.fields.buffering]]
  75. == Field Buffering
  76. Field components implement the [interfacename]#Buffered# and
  77. [interfacename]#BufferedValidatable# interfaces. When buffering is enabled for a
  78. field with [methodname]#setBuffered(true)#, the value is not written to the
  79. property data source before the [methodname]#commit()# method is called for the
  80. field. Calling [methodname]#commit()# also runs validators added to the field,
  81. and if any fail (and the [parameter]#invalidCommitted# is disabled), the value
  82. is not written.
  83. [source, java]
  84. ----
  85. form.addComponent(new Button("Commit",
  86. new Button.ClickListener() {
  87. @Override
  88. public void buttonClick(ClickEvent event) {
  89. try {
  90. editor.commit();
  91. } catch (InvalidValueException e) {
  92. Notification.show(e.getMessage());
  93. }
  94. }
  95. }));
  96. ----
  97. See the http://demo.vaadin.com/book-examples-vaadin7/book#component.field.buffering.basic[on-line example, window="_blank"].
  98. Calling [methodname]#discard()# reads the value from the property data source to
  99. the current input.
  100. If the fields are bound in a [classname]#FieldGroup# that has buffering enabled,
  101. calling [methodname]#commit()# for the group runs validation on all fields in
  102. the group, and if successful, all the field values are written to the item data
  103. source. See
  104. <<dummy/../../../framework/datamodel/datamodel-itembinding#datamodel.itembinding.buffering,"Buffering
  105. Forms">>.
  106. [[components.fields.validation]]
  107. == Field Validation
  108. The input for a field component can be syntactically or semantically invalid.
  109. Fields implement the [interfacename]#Validatable# interface, which allows
  110. checking validity of the input with __validators__ that implement the
  111. [interfacename]#Validator# interface. You can add validators to fields with
  112. [methodname]#addValidator()#.
  113. [source, java]
  114. ----
  115. TextField field = new TextField("Name");
  116. field.addValidator(new StringLengthValidator(
  117. "The name must be 1-10 letters (was {0})",
  118. 1, 10, true));
  119. field.setNullRepresentation("");
  120. field.setNullSettingAllowed(true);
  121. layout.addComponent(field);
  122. ----
  123. See the http://demo.vaadin.com/book-examples-vaadin7/book#component.field.validation.basic[on-line example, window="_blank"].
  124. Failed validation is indicated with the error indicator of the field, described
  125. in
  126. <<dummy/../../../framework/application/application-errors#application.errors.error-indicator,"Error
  127. Indicator and Message">>, unless disabled with
  128. [methodname]#setValidationVisible(false)#. Hovering mouse on the field displays
  129. the error message given as a parameter for the validator. If validated
  130. explicitly with [methodname]#validate()#, as described later, the
  131. [classname]#InvalidValueException# is thrown if the validation fails, also
  132. carrying the error message. The value [literal]#++{0}++# in the error message
  133. string is replaced with the invalid input value.
  134. Validators validate the property type of the field after a possible conversion,
  135. not the presentation type. For example, an [classname]#IntegerRangeValidator#
  136. requires that the value type of the property data source is
  137. [classname]#Integer#.
  138. [[components.fields.validation.builtin]]
  139. === Built-in Validators
  140. Vaadin includes the following built-in validators. The property value type is
  141. indicated.
  142. [classname]#BeanValidator#::
  143. Validates a bean property according to annotations defined in the Bean Validation API 1.0 (JSR-303).
  144. This validator is usually not used explicitly, but they are created implicitly when binding fields in a [classname]#BeanFieldGroup#.
  145. Using bean validation requires an implementation library of the API.
  146. See <<dummy/../../../framework/datamodel/datamodel-itembinding#datamodel.itembinding.beanvalidation,"Bean Validation">> for details.
  147. [classname]#CompositeValidator#::
  148. Combines validators using logical AND and OR operators.
  149. [classname]#DateRangeValidator#: [classname]#Date#::
  150. Checks that the date value is within the range at or between two given dates/times.
  151. [classname]#DoubleRangeValidator#: [classname]#Double#::
  152. Checks that the double value is at or between two given values.
  153. [classname]#EmailValidator#: [classname]#String#::
  154. Checks that the string value is a syntactically valid email address.
  155. The validated syntax is close to the RFC 822 standard regarding email addresses.
  156. [classname]#IntegerRangeValidator#: [classname]#Integer#::
  157. Checks that the integer value is at or between two given values.
  158. [classname]#NullValidator#::
  159. Checks whether the value is or is not a null value.
  160. +
  161. For the validator to be meaningful, the component must support inputting null
  162. values. For example, for selection components and [classname]#TextField#,
  163. inputting null values can be enabled with [methodname]#setNullSettingAllowed()#.
  164. You also need to set the representation of null values: in selection components
  165. with [methodname]#setNullSelectionItemId()# and in [classname]#TextField# with
  166. [methodname]#setNullRepresentation()#.
  167. ifdef::web[]
  168. +
  169. Setting field as __required__ can be used for similar effect, and it also
  170. enables an indicator to indicate that a value is required.
  171. endif::web[]
  172. [classname]#RegexpValidator#: [classname]#String#::
  173. Checks that the value matches with the given regular expression.
  174. [classname]#StringLengthValidator#: [classname]#String#::
  175. Checks that the length of the input string is at or between two given lengths.
  176. ifdef::web[]
  177. +
  178. The [parameter]#allowNull# parameter determines whether null values should be
  179. allowed for the string, regardless of the string length. A null value has zero
  180. length, so it will be invalid if the minimum length is greater than zero.
  181. Allowing null value is meaningful only if inputting null values is enabled with
  182. [methodname]#setNullSettingAllowed(true)#, and typically in such case, you want
  183. to set the null representation to empty string with
  184. [methodname]#setNullRepresentation("")#. Note that _this parameter is
  185. deprecated_ and should normally be [parameter]#true#; then you can use
  186. [methodname]#setRequired()# (for the false case) or [classname]#NullValidator#.
  187. endif::web[]
  188. Please see the API documentation for more details.
  189. [[components.fields.validation.automatic]]
  190. === Automatic Validation
  191. The validators are normally, when [literal]#++validationVisible++# is true for
  192. the field, executed implicitly on the next server request if the input has
  193. changed. If the field is in immediate mode, it (and any other fields with
  194. changed value) are validated immediately when the focus leaves the field.
  195. [source, java]
  196. ----
  197. TextField field = new TextField("Name");
  198. field.addValidator(new StringLengthValidator(
  199. "The name must be 1-10 letters (was {0})",
  200. 1, 10, true));
  201. field.setImmediate(true);
  202. field.setNullRepresentation("");
  203. field.setNullSettingAllowed(true);
  204. layout.addComponent(field);
  205. ----
  206. See the http://demo.vaadin.com/book-examples-vaadin7/book#component.field.validation.basic[on-line example, window="_blank"].
  207. [[components.fields.validation.explicit]]
  208. === Explicit Validation
  209. The validators are executed when the [methodname]#validate()# or
  210. [methodname]#commit()# methods are called for the field.
  211. [source, java]
  212. ----
  213. // A field with automatic validation disabled
  214. final TextField field = new TextField("Name");
  215. field.setNullRepresentation("");
  216. field.setNullSettingAllowed(true);
  217. layout.addComponent(field);
  218. // Define validation as usual
  219. field.addValidator(new StringLengthValidator(
  220. "The name must be 1-10 letters (was {0})",
  221. 1, 10, true));
  222. // Run validation explicitly
  223. Button validate = new Button("Validate");
  224. validate.addClickListener(new ClickListener() {
  225. @Override
  226. public void buttonClick(ClickEvent event) {
  227. field.setValidationVisible(false);
  228. try {
  229. field.validate();
  230. } catch (InvalidValueException e) {
  231. Notification.show(e.getMessage());
  232. field.setValidationVisible(true);
  233. }
  234. }
  235. });
  236. layout.addComponent(validate);
  237. ----
  238. See the http://demo.vaadin.com/book-examples-vaadin7/book#component.field.validation.explicit[on-line example, window="_blank"].
  239. [[components.fields.validation.custom]]
  240. === Implementing a Custom Validator
  241. You can create custom validators by implementing the [interfacename]#Validator#
  242. interface and implementing its [methodname]#validate()# method. If the
  243. validation fails, the method should throw either
  244. [classname]#InvalidValueException# or [classname]#EmptyValueException#.
  245. [source, java]
  246. ----
  247. class MyValidator implements Validator {
  248. @Override
  249. public void validate(Object value)
  250. throws InvalidValueException {
  251. if (!(value instanceof String &&
  252. ((String)value).equals("hello")))
  253. throw new InvalidValueException("You're impolite");
  254. }
  255. }
  256. TextField field = new TextField("Say hello");
  257. field.addValidator(new MyValidator());
  258. field.setImmediate(true);
  259. layout.addComponent(field);
  260. ----
  261. See the http://demo.vaadin.com/book-examples-vaadin7/book#component.field.validation.customvalidator[on-line example, window="_blank"].
  262. [[components.fields.validation.fieldgroup]]
  263. === Validation in Field Groups
  264. If the field is bound to a [classname]#FieldGroup#, described in
  265. <<dummy/../../../framework/datamodel/datamodel-itembinding#datamodel.itembinding,"Creating
  266. Forms by Binding Fields to Items">>, calling [methodname]#commit()# for the
  267. group runs the validation for all the fields in the group, and if successful,
  268. writes the input values to the data source.
  269. (((range="endofrange", startref="term.components.fields")))