Docs

Documentation versions (currently viewingVaadin 24)

Auto Form Hilla React

Auto Form is a component that renders a form for editing, updating and deleting items from a backend service.

Auto Form is a component that automatically renders a form for editing, updating and deleting items from a backend service.

Important
Scaled down examples
The examples on this page are scaled down so that their viewport-size-dependent behavior can be demonstrated. Some examples also change their behavior based on your browser viewport size.

Basic Usage

Auto Form requires a Java service that implements the CrudService<T, ID> interface. In the example here, the EmployeeService class extends CrudRepositoryService<T, ID, R>, which in turn implements the CrudService<T, ID>:

Source code
EmployeeService.java
Employee.java
EmployeeRepository.java

Hilla generates TypeScript objects for each @BrowserCallable service implementing the CrudService<T, ID> interface. These TypeScript objects have callable methods that execute the corresponding Java service methods, enabling the Add, Update, and Delete operations, as well as lazy data loading with sorting and filtering.

For the example above, you can import the generated TypeScript objects in your React view and configure the component like so:

Source code
tsx
<AutoForm service={EmployeeService} model={EmployeeModel} />

Here’s how the rendered form would look:

Open in a
new tab
Source code
auto-form-basic.tsx

As you can see, Auto Form component renders a form with fields for all properties of the Employee entity. When submitting the form, the data is automatically submitted to the save method of the configured CrudService.

Auto Form supports working with plain, non-JPA classes. This can be useful, for example, if you want to use the Data Transfer Object (DTO) pattern. See the Working with Plain Java Classes section for more on this.

Note
Default Responsive Breakpoints
Auto Form uses the Form Layout component's default responsive breakpoints. To learn how to customize them, see the Customizing Form Layout section.

Customizing Visibility & Order

Auto Form renders by default input fields for all properties of the entity in a Form Layout with a two-column layout, except for the properties annotated by @Id and @Version. You can customize the visibility and the order of fields using visibleFields property:

Open in a
new tab
Source code
auto-form-field-visibility.tsx

Alternatively, you can also use the hiddenFields property to specify which fields should be hidden.

Caution
Don’t Expose Sensitive Data on Client-Side
When using Auto Form, it’s important to check that you don’t expose sensitive data to the client-side. For example, if you have a password property in your entity, hiding it using visibleFields or hiddenFields doesn’t prevent the data from being sent to the client-side. Make sure your service implementation doesn’t expose sensitive data to the client-side. You could do this by using a @JsonIgnore annotation on the property.

Customizing Field Properties

You can customize the properties of the fields rendered by Auto Form by using the fieldOptions property.

Overriding Field Options

You can customize some options of the automatically rendered fields by Auto Form by using the fieldOptions property.

Customizing Field Label

To customize the label of a field, use the label property of the fieldOptions property as follows:

Open in a
new tab
Source code
auto-form-field-custom-label.tsx

The previous example shows how to customize the label of the firstName and lastName fields.

Customizing Field Column Span

As Auto Form component uses the Form Layout component as the layout, you can customize the colspan property of the fields rendered by Auto Form, with the fieldOptions property as follows:

Open in a
new tab
Source code
auto-form-field-colspan.tsx

Customizing Input Component

You can use the renderer property of the fieldOptions to override the rendered field by Auto Form. The following example shows how to render a Text Area component for the description field:

Open in a
new tab
Source code
auto-form-field-custom-renderer.tsx

Customizing Form Layout

You can customize the Form Layout component used by Auto Form, with the formLayoutProps property. For example, you can set the responsiveSteps property to customize the responsive breakpoints of the Form Layout component:

Open in a
new tab
Source code
auto-form-responsive-steps.tsx

Using Custom Renderer

To render a form in a completely different layout, you can use a custom renderer to define any arbitrary layout using the layoutRenderer property. Define a function that takes the AutoFormLayoutRendererProps as a parameter, that returns any React element. The parameter will contain the following properties:

  • children, the read-only list of bound fields; and

  • form, the form binder instance.

Since the children property is a read-only list of bound fields, you can use them in your custom renderer. The following example shows how to use the children property to render the fields in separate sub-form sections using the Vertical and Horizontal layouts:

Open in a
new tab
Source code
auto-form-custom-renderer-alt.tsx

Alternatively, you can manually create input fields, and use the form instance to connect them to the form.

The following example shows how to render fields, manually:

Open in a
new tab
Source code
auto-form-custom-renderer.tsx

Managing Form State

Auto Form component allows you to manage the form state in different scenarios. For instance, you can edit an item — versus creating a new one — by handling after submission events, and so on.

The following properties are available for managing the form state or reacting to form events:

  • item is the item to be edited. If the item is null, the form is in new mode, otherwise it is in edit mode;

  • disabled disables the whole form; and

  • onSubmitSuccess is a callback function that’s called after the form is submitted successfully.

The following example shows how to use the item property to manage switching between new and edit modes, and onSubmitSuccess for informing the user about the form submission success. Additionally, it uses disabled property to toggle the form’s disabled state:

Open in a
new tab
Source code
auto-form-edit-new-modes.tsx

Auto Form component supports Deletion functionality, which is associated with calling the delete method from the CrudService introduced to the Auto Form. The following properties are associated with managing this functionality:

  • deleteButtonVisible is to stipulate whether to show the delete button in the form, which is hidden by default. If enabled, the delete button is only shown when editing an existing item: that means that item property is not null.

  • onDeleteSuccess is a callback function that’s called after the item is deleted successfully.

The following example shows how to use the deleteButtonVisible property to show the Delete button, and uses the onDeleteSuccess property to inform the user about the deletion success. You can toggle between the edit and new modes to see its effect on the visibility of the Delete button in action:

Open in a
new tab
Source code
auto-form-delete-after-delete.tsx

The following properties are associated with managing the form actions error handling:

  • onSubmitError is a callback that’s called if an unexpected error occurs while submitting the form. The callback receives the error as a parameter.

  • onDeleteError is a callback that’s called if an unexpected error occurs while deleting the item. The callback receives the error as a parameter.

The next example shows how to use the onSubmitError and onDeleteError callbacks to inform the user about their respective errors:

Source code
auto-form-on-errors.tsx
Note
On Submit Error Not Called
Note that onSubmitError callback is not be called for form validation errors, which are handled automatically.

Validation

Auto Form uses the same validation mechanism as 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.

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

Source code
Using Bean Validation Annotations
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

public class Employee {
    @NotNull
    @NotBlank
    private String firstName;

    // ...
}

For further information on using validation, refer to the Forms 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:

Source code
Using Custom Client-Side Validators in Auto Form
<AutoForm
  service={EmployeeService}
  model={EmployeeModel}
  fieldOptions={{
    firstName: {
      validators: [
        {
          message: 'First name must be longer than 3 characters',
          validate: (value: string) => value.length > 3,
        },
      ],
    },
  }}
/>

Working with Plain Java Classes

Auto Form supports working with plain, non-JPA Java classes. This can be useful, for example if you want to use the Data Transfer Object (DTO) pattern to decouple your domain from your presentation logic, or you want to avoid serializing your JPA entities to the client due to performance concerns.

Implementing a Custom Service

To use plain Java classes, you need to provide a custom implementation of the FormService<T> interface. The following methods need to be implemented:

  • T save(T value): Either creates a new item or updates an existing one, depending on whether the item has an ID or not. Returns the saved item.

  • void delete(ID id): Deletes the item with the given ID.

The following example shows a basic implementation of a custom FormService that wraps a JPA repository. The service only accepts DTO instances from the client and maps between the DTO instances and JPA entities internally.

Source code
ProductDtoFormService.java
ProductDto.java
Product.java
ProductRepository.java