Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion articles/building-apps/forms-data/add-form/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ In business applications, forms play a central role in *displaying and collectin

Vaadin offers a range of components and utilities to simplify form building. However, because forms and data binding cover a broad area, the topic is divided into several focused guides. Each one covers a specific aspect of form development.

The guides use Flow views. For forms in React views, see the <</hilla/guides/forms#,Forms>> reference guide.
The guides use Flow views. For forms in React views, see the <<{articles}/flow/react-views/forms#,Forms>> reference guide.

section_outline::[]
Original file line number Diff line number Diff line change
Expand Up @@ -372,4 +372,4 @@ If you now use the `Quantity` domain primitive in a <<{articles}/flow/react-view

Multi-value domain primitives are converted into their own TypeScript types, as long as they meet the requirements of the <<{articles}/flow/react-views/browser-callable-services/type-conversion#objects,type conversion>> for objects.

The input is validated on the server side by the domain primitive constructors, during JSON deserialization. However, an `IllegalArgumentException` thrown here becomes a `400 Bad Request` on the client side. The client is able to deduce that this is a validation error, but not from which field. Your system remains safe from bad data, but the user experience is not good. To improve it, you have to <<{articles}/hilla/guides/forms/binder-validation#defining-custom-client-side-validators,define custom client-side validators>> on your fields.
The input is validated on the server side by the domain primitive constructors, during JSON deserialization. However, an `IllegalArgumentException` thrown here becomes a `400 Bad Request` on the client side. The client is able to deduce that this is a validation error, but not from which field. Your system remains safe from bad data, but the user experience is not good. To improve it, add <<{articles}/flow/react-views/forms/validation#field-validators,validators>> to the fields in the view.
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public class UserService {
}
----

Bean Validation annotations have the added benefit of being supported by both Flow views and React views, for use in user interface validation. For more information about this, see the relevant <<{articles}/flow/binding-data/components-binder-beans#using-jsr-303-bean-validation,Flow>> and <<{articles}/hilla/guides/forms/binder-validation#,React>> documentation pages.
Bean Validation annotations have the added benefit of being supported by both Flow views and React views, for use in user interface validation. For more information about this, see the relevant <<{articles}/flow/binding-data/components-binder-beans#using-jsr-303-bean-validation,Flow>> and <<{articles}/flow/react-views/forms/validation#,React>> documentation pages.

For more information about Jakarta Bean Validation, visit the https://beanvalidation.org/[Bean Validation website]. For more information about using Bean Validation in Spring, see the https://docs.spring.io/spring-framework/reference/core/validation/beanvalidation.html[Spring documentation].

Expand Down
2 changes: 1 addition & 1 deletion articles/building-apps/react/add-view.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ Avoid explicit routes unless necessary. Letting the routing system resolve route

== Building Forms in a View

To collect and edit data in a React view, combine Vaadin input components with the `useForm` hook, which binds fields to a Java data type and applies the same validation rules on the client. Forms are an in-depth topic of their own; see the <<{articles}/hilla/guides/forms#,Forms reference guide>> for field binding, validation, and loading and saving data.
To collect and edit data in a React view, combine Vaadin input components with the `useForm` hook, which binds fields to a Java data type and applies the same validation rules on the client. Forms are an in-depth topic of their own. See the <<{articles}/flow/react-views/forms#,Forms reference guide>> for field binding, validation, and loading and saving data.


== Next Steps
Expand Down
2 changes: 1 addition & 1 deletion articles/components/_input-field-common-features.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ A separate single-character, regular expression can be used to restrict the char
// tag::binder[]
.Data Binding & Custom Validation
[NOTE]
Flow and Hilla offer an advanced API called Binder that allows you to bind data and add custom validation rules for multiple fields, creating forms. You can learn more about Binder from the corresponding <<{articles}/flow/binding-data/components-binder-validation#,Flow>> and <<{articles}/hilla/guides/forms/binder-validation#,Hilla>> articles.
Flow and React views can bind fields to the properties of a data object and validate them, creating forms. You can learn more from the corresponding <<{articles}/flow/binding-data/components-binder-validation#,Flow>> and <<{articles}/flow/react-views/forms/validation#,React>> articles.
// end::binder[]


Expand Down
4 changes: 2 additions & 2 deletions articles/components/auto-form/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ Note that `onSubmitError` callback is not be called for form validation errors,

== Validation

Auto Form uses the same validation mechanism as <</hilla/guides/forms/binder-validation#,default Hilla Forms>>. You can add Bean validation annotations to your entity classes, and the form automatically validates the input values on both client and server.
Auto Form uses the same validation mechanism as <<{articles}/flow/react-views/forms/validation#,forms in React views>>. You can add Bean validation annotations to your entity classes, and the form automatically validates the input values on both client and server.

In the following example, annotations are added to the `Employee` class to ensure that `firstName` is neither `null` nor an empty string:

Expand All @@ -255,7 +255,7 @@ public class Employee {
}
----

For further information on using validation, refer to the <</hilla/guides/forms/binder-validation#,Forms>> documentation.
For further information on using validation, refer to the <<{articles}/flow/react-views/forms/validation#,Form Validation>> documentation.

One notable difference to default forms is adding custom client-side validators. With Auto Form, custom client-side validators are added using the `validators` property in the `fieldOptions`. The following example shows how to add a custom validator to the `firstName` field:

Expand Down
2 changes: 1 addition & 1 deletion articles/components/date-picker/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ include::{root}/frontend/demo/component/datepicker/react/date-picker-custom-vali
endif::[]
--

Binder can also be used to organize data binding and validation for multiple fields, creating forms. You can learn more about Binder from the corresponding <<{articles}/flow/binding-data/components-binder-validation#,Flow>> and <<{articles}/hilla/guides/forms/binder-validation#,Hilla>> articles.
Binder can also be used to organize data binding and validation for multiple fields, creating forms. You can learn more about forms from the corresponding <<{articles}/flow/binding-data/components-binder-validation#,Flow>> and <<{articles}/flow/react-views/forms/validation#,React>> articles.


[[configuring-individual-dates]]
Expand Down
2 changes: 1 addition & 1 deletion articles/components/date-time-picker/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ include::{root}/frontend/demo/component/datetimepicker/react/date-time-picker-cu
endif::[]
--

Binder can also be used to organize data binding and validation for multiple fields, creating forms. You can learn more about Binder from the corresponding <<{articles}/flow/binding-data/components-binder-validation#,Flow>> and <<{articles}/hilla/guides/forms/binder-validation#,Hilla>> articles.
Binder can also be used to organize data binding and validation for multiple fields, creating forms. You can learn more about forms from the corresponding <<{articles}/flow/binding-data/components-binder-validation#,Flow>> and <<{articles}/flow/react-views/forms/validation#,React>> articles.


== Week Numbers
Expand Down
2 changes: 1 addition & 1 deletion articles/components/time-picker/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ include::{root}/frontend/demo/component/timepicker/react/time-picker-custom-vali
endif::[]
--

Binder can also be used to organize data binding and validation for multiple fields, creating forms. You can learn more about Binder from the corresponding <<{articles}/flow/binding-data/components-binder-validation#,Flow>> and <<{articles}/hilla/guides/forms/binder-validation#,Hilla>> articles.
Binder can also be used to organize data binding and validation for multiple fields, creating forms. You can learn more about forms from the corresponding <<{articles}/flow/binding-data/components-binder-validation#,Flow>> and <<{articles}/flow/react-views/forms/validation#,React>> articles.


// Basic Features
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ The client that the service modules use, unless the project has a client of its
A TypeScript type for each Java type that the services use, in directories named after the Java package. A nested class has a directory named after the enclosing class, such as [filename]`Sort/Direction.ts`. See <<type-conversion#,Type Conversion>>.

[filename]`{package}/{type}Model.ts`::
A model of each type, for binding forms to it. See <<{articles}/hilla/guides/forms/binder#,Binding Data to Forms>>.
A model of each type, for binding forms to it. See <<../forms#,Forms>>.

[filename]`{package}/{type}Union.ts`::
A union of the subtypes of a polymorphic type. See <<type-conversion#polymorphic-types,Polymorphic Types>>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ include::{root}/frontend/demo/fusion/errorhandling/catch-invalid-args.ts[]

A method can also fail a call with an `EndpointValidationError` by throwing an [classname]`EndpointValidationException`. Vaadin also checks the constraints on the return value. When the return value fails them, the call fails as described in <<#errors,Errors>>.

When a form bound with the `useForm` hook submits its value to a service method, the form shows the validation errors of the call in its fields. See <<{articles}/hilla/guides/forms/binder-validation#,Form Validation>>.
When a form bound with the `useForm` hook submits its value to a service method, the form shows the validation errors of the call in its fields. See <<../forms#server-validation,Server-Side Validation>>.


[[errors]]
Expand Down
2 changes: 1 addition & 1 deletion articles/flow/react-views/component-events.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ include::{root}/frontend/demo/fusion/application/events/value-changed-view.tsx[r

React passes the custom events of Vaadin components, such as `value-changed`, to the listener as they are. For standard browser events, such as `click`, React passes its own synthetic event instead. The browser event is then in `event.nativeEvent`.

To keep a form's state in sync with its fields without handling their change events, bind the fields with the `useForm` hook. See <<{articles}/hilla/guides/forms/binder#,Binding Data to Forms>>.
To keep a form's state in sync with its fields without handling their change events, bind the fields with the `useForm` hook. See <<forms#,Forms>>.
109 changes: 109 additions & 0 deletions articles/flow/react-views/forms/api.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
title: Form API
page-title: Hooks and types of form binding in React views | Vaadin
description: The hooks that bind forms in React views, their results, and the types for validation.
meta-description: API reference for Vaadin form binding in React views - useForm, useFormPart, useFormArrayPart, the field function, validators, errors, and form models.
order: 50
---


= Form API
:toclevels: 2

The hooks of form binding are in the `@vaadin/hilla-react-form` package. The validation types are in `@vaadin/hilla-lit-form`, and the model helpers in `@vaadin/hilla-models`.

section_outline::[]


[[use-form]]
== useForm

`useForm(model, config?)` creates a form for the given model, and returns its state and functions. The optional configuration object has these properties:

`onSubmit(value)`::
An asynchronous function that [methodname]`submit()` calls with the value of the form. See <<index#submitting,Submitting>>.

`onChange(oldValue)`::
A function that the form calls when it updates its value, with the value before the update.

The result has the state properties described in <<form-state#properties,Form State>>, and these functions:

`field(model)`::
Returns the properties that bind a component to the field of the given model. Spread them on the component. See <<field-components#,Field Components>>.

`read(value)`::
Sets the value and the default value of the form, and clears the validation errors. With `null` or `undefined`, it clears the form.

`reset()`::
Sets the value back to the default value.

`clear()`::
Sets the value and the default value to the default values of the model.

`submit()`::
Validates the form, and calls `onSubmit`. Returns a promise that resolves with the result of `onSubmit`, or rejects with a [classname]`ValidationError`.

`setValue(value)`::
Sets the value of the form.

`setDefaultValue(value)`::
Sets the default value of the form, which affects the `dirty` state and [methodname]`reset()`.

`validate()`::
Validates the form, and returns a promise of its errors.

`addValidator(validator)`::
Adds a validator to the form. See <<validation#form-validators,Form Validators>>.

`setValidators(validators)`::
Replaces the validators of the form.

`setVisited(visited)`::
Sets the `visited` state.

`update()`::
Re-renders the component.


[[use-form-part]]
== useFormPart

`useFormPart(model)` returns the state and functions of a part of a form, such as a field or a nested object. The model must belong to a form that a [methodname]`useForm()` call in the same or a parent component created.

The result has the state properties described in <<form-state#properties,Form State>>, except `submitting`, and the `field()`, `setValue()`, `validate()`, `addValidator()`, `setValidators()`, and `setVisited()` functions of [methodname]`useForm()`. They apply to the part.

The validators of a field include the validators of its Bean Validation constraints. Calling [methodname]`setValidators()` replaces them, too.


[[use-form-array-part]]
== useFormArrayPart

`useFormArrayPart(model)` returns the state and functions of a list or an array in a form, like [methodname]`useFormPart()`, but without `field()`. Its `items` property contains a model for each item. The model must be non-nullable. See <<nested-objects-arrays#arrays,Arrays>>.


[[validation-types]]
== Validation Types

The `@vaadin/hilla-lit-form` package has these types for validation:

[classname]`Validator`::
An object with a `message`, a [methodname]`validate(value)` function, and an optional `impliesRequired` flag. See <<validation#validators,Validators in the View>>.

[classname]`ValueError`::
A validation error, with the `property` that identifies the field, the `message`, the `value`, and the `validator` that failed.

[classname]`ValidationError`::
The error that [methodname]`submit()` rejects with when the validation fails. Its `errors` property contains the [classname]`ValueError` objects.

[classname]`BinderRoot`::
Its static `interpolateMessageCallback` property replaces the placeholders in the messages of constraints. See <<validation#messages,Error Messages>>.

The package also has a validator class for each Bean Validation constraint that the browser checks, such as [classname]`NotBlank`, [classname]`Size`, and [classname]`Pattern`. They take an options object with a `message` and the attributes of the constraint, such as `new Size({ min: 3, max: 20 })`.


[[models]]
== Form Models

A generated form model, such as `PersonModel`, is both a value and a type with the same name. Pass the value to the hooks, and use the type for the properties of components that get a part of the form.

The `$defaultValue` symbol from `@vaadin/hilla-models` gives the default value of a model, such as `PersonModel[$defaultValue]`.
66 changes: 66 additions & 0 deletions articles/flow/react-views/forms/field-components.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: Field Components
page-title: Field components that bind to forms in React views | Vaadin
description: The Vaadin components that the field() function binds, and the Java types of the properties that they edit.
meta-description: Reference for Vaadin forms in React views - which Vaadin field components the field() function binds, and the Java property types that each of them edits.
order: 40
---


= Field Components

The [methodname]`field()` function binds the following Vaadin components. Each component edits a property of one of the listed Java types:
Comment thread
peholmst marked this conversation as resolved.
Resolved

[cols="2,3"]
|===
|Component |Java type of the property

|<<{articles}/components/text-field#,Text Field>>, <<{articles}/components/text-area#,Text Area>>, <<{articles}/components/password-field#,Password Field>>, <<{articles}/components/email-field#,Email Field>>
|`String`

|<<{articles}/components/number-field#,Integer Field, Number Field>>
|A number type, such as `int`, `Integer`, `double`, or `BigDecimal`

|<<{articles}/components/checkbox#,Checkbox>>
|`boolean`

|<<{articles}/components/date-picker#,Date Picker>>
|`LocalDate`

|<<{articles}/components/time-picker#,Time Picker>>
|`LocalTime`

|<<{articles}/components/date-time-picker#,Date Time Picker>>
|`LocalDateTime`

|<<{articles}/components/select#,Select>>, <<{articles}/components/radio-button#,Radio Button Group>>
|`String` or an enum, matched to the values of the items

|<<{articles}/components/combo-box#,Combo Box>>
|`String` or an enum, matched to the values of the items, or an object, which is the selected item

|<<{articles}/components/checkbox#,Checkbox Group>>
|A list or a set of `String`

|<<{articles}/components/multi-select-combo-box#,Multi-Select Combo Box>>
|A list or a set of the items

|<<{articles}/components/custom-field#,Custom Field>>
|`String`. By default, the value combines the values of the fields inside the custom field, separated by tab characters.

|<<{articles}/components/rich-text-editor#,Rich Text Editor>>
|`String`, in the Delta format of the editor
|===

For example, a combo box can edit a `Country` property of a form, when its items are `Country` objects:

[source,tsx]
----
<ComboBox label="Country" items={countries} itemLabelPath="name" itemValuePath="name" {...field(model.country)} />
----

See <<form-state#changing-values,Changing Values from Code>> for the whole example.

When the user empties a number field, the value of a nullable number becomes `undefined`. A non-nullable number becomes `NaN`, and the field shows the error "must be a number".

The [methodname]`field()` function throws an error for a component that isn't a field, such as a <<{articles}/components/list-box#,List Box>>. It doesn't read the state of a <<{articles}/components/switch#,Switch>>, so use a checkbox for a `boolean` property instead.
Loading
Loading