> Markdown version of [Binding Data to Forms](https://vaadin.com/docs/v14/flow/binding-data/tutorial-flow-components-binder). Section index: [llms.txt](https://vaadin.com/docs/v14/flow/llms.txt)

# Binding Data to Forms

In many applications users provide structured data by completing fields in forms. This data is typically represented in code as an instance of a business object (JavaBean), for example a Person in an HR application.

The `Binder` class allows you to define how the values in a business object are bound to fields in the UI.

`Binder` reads the values in the business object and converts them from the format expected by the business object to the format expected by the field, and *vice versa*.

`Binder` can only bind components that implement the `HasValue` interface, for example `TextField` and `ComboBox`.

It is also possible to validate user input and present the validation status to the user in different ways.

## <a id="how-to-bind-form-data"></a>How to Bind Form Data

The following steps include everything needed to load, edit and save values for a form. Java 8 method references are used.

To bind data to a form:

1. Create a `Binder` and bind the input fields.

   > **Note:** There can only be one `Binder` instance for each form. You should use it for all fields in the form.

   ```java
   Binder<Person> binder = new Binder<>(Person.class);

   TextField titleField = new TextField();

   // Start by defining the Field instance to use
   binder.forField(titleField)
           // Finalize by doing the actual binding
           // to the Person class
           .bind(
                   // Callback that loads the title
                   // from a person instance
                   Person::getTitle,
                   // Callback that saves the title
                   // in a person instance
                   Person::setTitle);

   TextField nameField = new TextField();

   // Shorthand for cases without extra configuration
   binder.bind(nameField, Person::getName,
           Person::setName);
   ```

2. Use the `Binder` to:

   1. Load values from a `person` into the field.

   2. Allow the user to edit the values.

   3. Save the values back into a `person` instance.

      ```java
      // The person to edit
      // Would be loaded from the backend
      // in a real application
      Person person = new Person("John Doe", 1957);

      // Updates the value in each bound field component
      binder.readBean(person);

      Button saveButton = new Button("Save",
          event -> {
              try {
                  binder.writeBean(person);
                  // A real application would also save
                  // the updated person
                  // using the application's backend
              } catch (ValidationException e) {
                  notifyValidationException(e);
              }
      });

      // Updates the fields again with the
      // previously saved values
      Button resetButton = new Button("Reset",
              event -> binder.readBean(person));
      ```

      - Every time `writeBean` is called, the data is validated and then copied from the UI to the business object.

      - If the data is invalid, a `ValidationException` that includes all errors in the data, is thrown. This is the reason `writeBean` is in a try/catch block.

It is also possible to use a Lambda expression, instead of a method reference.

```java
// With lambda expressions
binder.bind(titleField,
        person -> person.getTitle(),
        (person, title) -> {
            person.setTitle(title);
            logger.info("setTitle: {}", title);
        });
```

## <a id="binding-read-only-data"></a>Binding Read-only Data

To bind a component to read-only data, you can use a `null` value for the `setter`.

**Example**: Using a `null` value setter.

```java
TextField fullName = new TextField();
binder.forField(fullName)
        .bind(Person::getFullName, null);
```

To bind components that do not implement the `HasValue` interface to read-only data, you can use the `ReadOnlyHasValue` helper class.

**Example**: Using the `ReadOnlyHasValue` helper class.

```java
Label fullNameLabel = new Label();
ReadOnlyHasValue<String> fullName =
        new ReadOnlyHasValue<>(
            text -> fullNameLabel.setText(text));
binder.forField(fullName)
        .bind(Person::getFullName, null);
```

`DB2C0A1D-7AB1-422D-B9C9-1E47A9D99768`
