> Markdown version of [Connect Contact Form to Java](https://vaadin.com/docs/next/tools/designer/getting-started/connecting-your-contact-form-to-java). Section index: [llms.txt](https://vaadin.com/docs/next/tools/llms.txt)

## <a id="java-contact-form"></a>Connecting Contact Form to Java (deprecated since V25.0)

> **Warning:** Vaadin Designer has been deprecated since V25.0, in favor of [Vaadin Copilot](https://vaadin.com/docs/next/tools/copilot.md). Going forward, Copilot is where the design-to-code workflow evolves.
>
> Designer still works with V25, but it’s no longer developed and it may be removed in a future version. It also doesn’t support the Aura theme.

Now that the work with the grid is complete, you still need to configure the contact form, and bind it to the values displayed in the grid.

## <a id="java-configure-contact-form"></a>Configure the Contact Form

To make it possible to bind the fields of a contact bean to the form, the form’s fields must be present as members in the `ContactForm` class. You can add the fields to the class using Designer, but need to be careful with naming them because Vaadin binder works by matching the bean and field names. The `Contact` bean has fields named: `firstName`, `lastName`, `email`, `company`, and `status`. When you connect the fields from `contact-form`, you need to use these exact names.

To do all of this, in Designer, open `contact-form`. Select the first name field, give it the `firstName` identifier attribute, and then connect it by clicking the Java icon in the outline. This connects the first name field with the `firstName` id.

Repeat these steps for the other fields and buttons in the form:

- Last name field: `lastName` identifier attribute.

- Email field: `email` identifier attribute.

- Company field: `company` identifier attribute.

- Status field: `status` identifier attribute.

- Save button: `save` identifier attribute.

- Delete button: `delete` identifier attribute.

- Close button: `close` identifier attribute.

[Image: Connect the form fields in Designer.]

After this is done in Designer, you should have the following fields in the `ContactForm` class:

`ContactForm.java`

```java
    @Id("firstName")
    private TextField firstName;
    @Id("lastName")
    private TextField lastName;
    @Id("email")
    private EmailField email;
    @Id("company")
    private ComboBox<String> company;
    @Id("status")
    private ComboBox<String> status;
    @Id("save")
    private Button save;
    @Id("delete")
    private Button delete;
    @Id("close")
    private Button close;
```

Two things must still be added in the `ContactForm` class. First, the items in the combo boxes are still not set. You can get the list of companies and statuses from the `ContactRepository`, and set the combo boxes using those lists. Second, you need to add getters for the save, delete, and close buttons so that you can use those from inside the `MainView` class to listen to events inside the form.

Here’s the full `ContactForm` class that implements the above changes:

`ContactForm.java`

```java
@Tag("contact-form")
@JsModule("./src/views/contact-form.ts")
public class ContactForm extends LitTemplate {

    @Id("firstName")
    private TextField firstName;
    @Id("lastName")
    private TextField lastName;
    @Id("email")
    private EmailField email;
    @Id("company")
    private ComboBox<String> company;
    @Id("status")
    private ComboBox<String> status;
    @Id("save")
    private Button save;
    @Id("delete")
    private Button delete;
    @Id("close")
    private Button close;

    public ContactForm(ContactRepository contactRepository) { // (1)
        company.setItems(contactRepository.findDistinctCompanies()); // (2)
        status.setItems(contactRepository.findDistinctStatuses()); // (3)
    }

    public Button getSave() { // (4)
        return save;
    }

    public Button getDelete() {
        return delete;
    }

    public Button getClose() {
        return close;
    }
}
```

1. Adds `ContactRepository` as a parameter. The Spring framework injects it here.

2. Sets the `company` combo box items by fetching them from `ContactRepository`.

3. Sets the `status` combo box items by fetching them from `ContactRepository`.

4. Add getters for the save, delete, and close buttons.

## <a id="connect-grid-form"></a>Connect Grid & Form

Now you need to ensure that when a contact is selected in the grid, the form is populated with the details from this contact. You also need to ensure that any modifications made to the contact object inside the form are persisted in the backend and that the grid is updated accordingly.

To do this, you change the `MainView` class one last time, so that it looks as follows:

`MainView.java`

```java
@Tag("main-view")
@JsModule("./src/views/main-view.ts")
@Route("")
public class MainView extends LitTemplate {

    @Id("filterText")
    private TextField filterText;
    @Id("addContactButton")
    private Button addContactButton;
    @Id("grid")
    private Grid<Contact> grid;
    @Id("contactForm")
    private ContactForm contactForm;

    private ContactRepository contactRepository;

    private Contact currentContact; // (1)

    private BeanValidationBinder<Contact> binder; // (2)

    public MainView(ContactRepository contactRepository) {
        this.contactRepository = contactRepository;

        grid.addColumn(Contact::getFirstName).setHeader("First name");
        grid.addColumn(Contact::getLastName).setHeader("Last name");
        grid.addColumn(Contact::getEmail).setHeader("Email");
        grid.addColumn(Contact::getCompany).setHeader("Company");
        grid.addColumn(Contact::getStatus).setHeader("Status");
        grid.getColumns().forEach(col -> col.setAutoWidth(true));
        updateList();

        filterText.setValueChangeMode(ValueChangeMode.LAZY);
        filterText.addValueChangeListener(e -> updateList());

        configureBinding(); // (3)
    }

    public void updateList() {
        String filterValue = filterText.getValue();
        if (filterValue == null || filterValue.isBlank()) {
            grid.setItems(contactRepository.findAll());
        } else {
            grid.setItems(contactRepository.findByFirstNameOrLastNameContainsIgnoreCase(filterValue, filterValue));
        }
    }

    private void configureBinding() {
        grid.asSingleSelect().addValueChangeListener(event -> {  // (4)
            Contact contact = event.getValue();
            if (contact != null) {
                populateForm(contact);
            } else {
                clearForm();
            }
        });

        binder = new BeanValidationBinder<>(Contact.class); // (5)
        binder.bindInstanceFields(contactForm); // (6)

        contactForm.getDelete().addClickListener(e -> { // (7)
            if (this.currentContact != null) {
                contactRepository.delete(this.currentContact); // (8)
                updateList();
                clearForm();
                Notification.show("Contact deleted.");
            }
        });

        contactForm.getClose().addClickListener(e -> { // (9)
            clearForm();
        });

        contactForm.getSave().addClickListener(e -> { // (10)
            try {
                if (this.currentContact == null) {
                    this.currentContact = new Contact();
                }
                binder.writeBean(this.currentContact); // (11)
                contactRepository.save(this.currentContact); // (12)
                updateList();
                clearForm();
                Notification.show("Contact details stored.");
            } catch (ValidationException validationException) {
                Notification.show("Please enter a valid contact details."); // (13)
            }
        });
    }

    void clearForm() {  // (14)
        populateForm(null);
    }

    void populateForm(Contact contact) {  // (15)
        this.currentContact = contact;
        binder.readBean(this.currentContact);
    }
}
```

1. An object to hold the currently selected contact.

2. A Vaadin `Binder` that uses reflection based on the provided `Contact` type to resolve bean properties. The Binder automatically adds `BeanValidator` which validates beans using Java Specification Requests (JSR) 303 specification.

3. Initiate binding configuration.

4. When a row is selected or deselected, populate or clear the form.

5. Instantiate the binder.

6. Bind the member fields found in the `ContactForm` object. This process is done automatically because the `ContactForm` object has member fields that are named identically to the fields found in the `Contact` bean.

7. Add a click listener to the delete button of the contact form in which the delete operations are performed.

8. Delete the currently selected contact from the backend, and refresh the grid afterwards.

9. Add a click listener to the close button of the form in which the form is cleared without making any modifications to the contact object.

10. Add a click listener to the save button of the contact form in which the save operations are performed.

11. Writes changes from the bound form fields to the `currentContact` object if all validators pass. If any field binding validator fails, no values are written and a `ValidationException` is thrown.

12. Save the `currentContact` object to the backend, after which update the grid and clear the form.

13. Show a notification a `ValidationException` is thrown. This can occur, for example, if the user tries to save a contact with a blank email field.

14. Clears the form

15. Populates the form with the provided contact.

That’s all. Now if you rerun the application, you’re able to see the form populated with the contact that was selected from the grid. Changes made to the form are now also updated in the backend and reflected in the grid.

Proceed to the last page and complete the tutorial: [Wrap Up](https://vaadin.com/docs/next/tools/designer/getting-started/wrap-up.md).

`E42C1CDB-4F42-46C9-8388-4423B2E045D5`
