> Markdown version of [Binding Data to Forms](https://vaadin.com/docs/latest/flow/binding-data/components-binder). Section index: [llms.txt](https://vaadin.com/docs/latest/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. It also handles the reverse process, converting values from UI fields to the format expected by the business object.

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

It’s 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.

To bind data to a form:

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

   > **Note:** There can be only one `Binder` instance for each form. You should use this instance for all the 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` is thrown, listing all the errors in the data. Hence, `writeBean()` is enclosed in a try/catch block.

It’s 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 don’t implement the `HasValue` interface to read-only data, you can use the `ReadOnlyHasValue` helper class.

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

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

`1BC1EEA8-75BE-4A79-AECA-4243E5FFDA30`
