I implemented a vaadin grid in buffered mode with a simple client pojo, it is pretty much the same as in the vaadin examples for buffered mode. Everything is ok, beside that saving is not possible when I try to change something in the edited fields. As soon as I change something, the save button and the editor will get stuck. All other things do as expected.
@Route(value = "")
public class ClientView extends VerticalLayout {
private final Logger LOGGER = LoggerFactory.getLogger(ClientView.class);
private List<Client> clientArrayList = new ArrayList<>();
private Grid<Client> grid = new Grid<>();
public ClientView() {
LOGGER.info("init clientview");
// test data
clientArrayList.add(new Client("tenant1", "client1", "name client1", "server1"));
clientArrayList.add(new Client("tenant1", "client2", "name client2", "server1"));
clientArrayList.add(new Client("tenant2", "client3", "name client3", "server1"));
clientArrayList.add(new Client("tenant2", "client4", "name client4", "server1"));
// button add new element
final Button btnAdd = new Button("Neue Einheit");
add(btnAdd);
// build grid
grid.setWidthFull();
grid.setHeight("800px");
final Grid.Column<Client> colClientId = grid.addColumn(Client::getClientId).setHeader("Kennung").setAutoWidth(true).setSortable(true);
final Grid.Column<Client> colClientName = grid.addColumn(Client::getClientName).setHeader("Name der Einheit").setAutoWidth(true).setSortable(true);
final Grid.Column<Client> colClientServerUrl = grid.addColumn(Client::getClientServerUrl).setHeader("Url zum Server").setAutoWidth(true).setSortable(true);
grid.setItems(clientArrayList);
// editing fields
final Binder<Client> binder = new Binder<>(Client.class);
final Editor<Client> editor = grid.getEditor();
editor.setBuffered(true);
editor.setBinder(binder);
// all three editing fields
final TextField tfClientId = new TextField();
tfClientId.setMinWidth("120px");
tfClientId.setPlaceholder("Kennung");
binder.forField(tfClientId)
.withValidator(value -> (value.length() > 0),"Kennung muss einen Wert enthalten").bind("clientId");
colClientId.setEditorComponent(tfClientId);
final TextField tfClientName = new TextField();
tfClientName.setMinWidth("240px");
tfClientName.setPlaceholder("Name der Einheit");
binder.forField(tfClientName)
.withValidator(value -> (value.length() > 0), "Name muss einen Wert enthalten").bind("clientName");
colClientName.setEditorComponent(tfClientName);
final TextField tfClientServerUrl = new TextField();
tfClientServerUrl.setMinWidth("360px");
tfClientServerUrl.setPlaceholder("http://localhost/");
binder.forField(tfClientServerUrl).bind("clientServerUrl");
colClientServerUrl.setEditorComponent(tfClientServerUrl);
// add editor column
final Collection<Button> editButtons = Collections.newSetFromMap(new WeakHashMap<>());
final Grid.Column<Client> editorColumn = grid.addComponentColumn(client -> {
final Button edit = new Button("Ändern");
edit.addClassName("edit");
edit.addClickListener(event -> {
editor.editItem(client);
tfClientId.focus();
LOGGER.info("editor click");
});
edit.setEnabled(!editor.isOpen());
editButtons.add(edit);
final Button delete = new Button("Löschen");
delete.addClassName("delete");
delete.addClickListener(event -> {
try {
delete(client);
reload();
} catch (Exception e) {
Notification.show("Die geänderte Einheit konnte nicht gespeichert werden!", 8000, Notification.Position.TOP_END);
}
LOGGER.info("delete click");
});
editButtons.add(delete);
final Div outsideEditor = new Div(edit, delete);
return outsideEditor;
});
// editor open listener
editor.addOpenListener(event -> {
editButtons.stream().forEach(button -> button.setEnabled(!editor.isOpen()));
LOGGER.info("addOpenListener");
});
// editor close listener
editor.addCloseListener(event -> {
editButtons.stream().forEach(button -> button.setEnabled(!editor.isOpen()));
LOGGER.info("addCloseListener");
});
// buttons for inside editor-mode
final Button save = new Button("Speichern", e -> {
editor.save();
LOGGER.info("save");
});
save.addClassName("save");
final Button cancel = new Button("Abbrechen", e -> {
editor.cancel();
LOGGER.info("cancel");
});
cancel.addClassName("cancel");
final Div insideEditor = new Div(cancel, save);
insideEditor.add(cancel, save);
editorColumn.setEditorComponent(insideEditor);
grid.getElement().addEventListener("keyup", event -> editor.cancel()).setFilter("event.key === 'Escape' || event.key === 'Esc'");
// editor save listener
editor.addSaveListener(event -> {
LOGGER.info("addSaveListener");
final Client client = event.getItem();
save(client);
editor.refresh();
});
// editor cancel listener
editor.addCancelListener(event -> {
LOGGER.info("addCancelListener");
});
// add a new client into list and edit that
btnAdd.addClickListener(event -> {
LOGGER.info("add click listener");
Client client = null;
try {
client = new Client("test", "", "", "");
clientArrayList.add(client);
reload();
editor.editItem(client);
} catch (Exception e) {
Notification.show("Die neue Einheit konnte nicht gespeichert werden!", 8000, Notification.Position.TOP_END);
}
});
// sets the max number of items to be rendered on the grid for each page
grid.setPageSize(15);
add(grid);
LOGGER.info("finish clientview");
}
private void reload() {
grid.setItems(clientArrayList);
}
private void delete(final Client client) {
// TODO
}
private void save(final Client client) {
// TODO
}
}
The client pojo is a simple class
public class Client implements Serializable {
private String tenantId;
private String clientId;
private String clientName;
private String clientServerUrl;
... all getters & setter & equals & hashcode & toString
}
I used a standard generated maven pom for vaadin with version 17.0.6 and deployed it to jetty to test on localhost.
What have I missed - I searched all available samples in the free world, but I didn’t see the hint, what I have to do??? Could you please give me a hint? Thanks!