Crud UI Add-on provides an API to automatically generate CRUD-like UIs for any Java Bean at runtime.
The API is defined through 4 interfaces:
CrudComponent
: A Vaadin Component
that can be added to any ComponentContainer
. This is the actual CRUD final users will see in the browser.
CrudListener
: Encapsulates the CRUD operations. You can implement this interface to delegate CRUD operations to your back-end.
CrudLayout
: Encapsulates layout-related behavior.
CrudFormFactory
: Builds the forms required by the CRUD UI.
The add-on includes several implementations of these interfaces.
There are three minor fixes in this forked version:
- Only show success notification if no CrudOperationException encountered
- More consistent grid selection following add/update operations
- Convention ordering of operation and cancel buttons on the default form
There are four minor enhancements in this forked version:
- Show error messages from CrudOperationException when relevant
- Provide ENTER shortcut for operation button on the form
- New method on grid to add an optional Update button column
- New method on form factory to enable/disable notifications, cf. the existing method on grid
Say, you have the following domain/entity/Java Bean class:
public class User {
@NotNull // Validation API is required! Add it as a dependency on your project
private Long id;
@NotNull
private String name;
private Date birthDate;
@Email
private String email;
@NotNull
private String password;
... getters & setters ...
}
You can create a new CRUD component and add it into any Vaadin layout as follows:
GridCrud<User> crud = new GridCrud<>(User.class);
layout.addComponent(crud);
You can enable Java Bean Validation as follows:
crud.getCrudFormFactory().setUseBeanValidation(true);
Use lambda expressions or method references to delegate CRUD operations to your backend:
crud.setFindAllOperation(() -> backend.findAll());
crud.setAddOperation(backend::add);
crud.setUpdateOperation(backend::update);
crud.setDeleteOperation(backend::delete);
As an alternative to method references and lambda expressions, you can implement a CrudListener
to delegate CRUD operations to your backend:
crud.setCrudListener(new CrudListener<User>() {
@Override
public Collection<User> findAll() {
return backend.findAllUsers();
}
@Override
public User add(User user) {
return backend.add(user);
}
@Override
public User update(User user) {
return backend.update(user);
}
@Override
public void delete(User user) {
backend.remove(user);
}
});
Use a different CrudLayout
implementation:
GridCrud<User> crud = new GridCrud<>(User.class, new HorizontalSplitCrudLayout());
Set a custom CrudFormFactory
:
CustomCrudFormFactory<User> formFactory = new CustomCrudFormFactory<>(User.class);
crud.setCrudFormFactory(formFactory);
Configure form fields visibility:
formFactory.setVisibleProperties(CrudOperation.READ, "name", "birthDate", "email", "groups", "mainGroup", "active");
formFactory.setVisibleProperties(CrudOperation.ADD, "name", "birthDate", "email", "password", "groups", "mainGroup", "active");
formFactory.setVisibleProperties(CrudOperation.UPDATE, "name", "birthDate", "email", "groups", "mainGroup", "active");
formFactory.setVisibleProperties(CrudOperation.DELETE, "name", "email");
Use nested properties in GridCrud
instances:
crud.getGrid().addColumn(user -> user.getMainGroup().getName()).setHeader("Main group").setKey("key");
Configure the type of an input field:
formFactory.setFieldType("password", PasswordField.class);
Customize fields after their creation:
formFactory.setFieldCreationListener("birthDate", field -> ... your own logic here ...);
Define a FieldProvider
to manually create a field:
formFactory.setFieldProvider("groups", user -> {
CheckboxGroup<Group> checkboxes = new CheckboxGroup<>();
checkboxes.setItems(groups);
checkboxes.setItemLabelGenerator(Group::getName);
return checkboxes;
});
Or use one of the included FieldProvider
implementations:
formFactory.setFieldProvider("groups",
new CheckBoxGroupProvider<>("Groups", GroupRepository.findAll(), Group::getName));
Set a Converter
:
formFactory.setConverter("salary", new Converter<String, BigDecimal>() {
@Override
public Result<BigDecimal> convertToModel(String value, ValueContext valueContext) {
return Result.ok(new BigDecimal(value)); // error handling omitted
}
@Override
public String convertToPresentation(BigDecimal value, ValueContext valueContext) {
return value.toPlainString();
}
});
Customize captions:
formFactory.setButtonCaption(CrudOperation.ADD, "Add new user");
crud.setRowCountCaption("%d user(s) found");