Hi, this is my first post on the forum.
I have the code shown below which represents a view with two main functionalities:
- A simple form that adds a new Object
- A grid that represents Objects in the database
I recently added the grid Edit functionality and then something strange happened.
After I click the Edit button some of my textFields that are in the form section disappear. I’ve noticed that those fields use binder object to set some validation or conversion. How can I fix this?
package com.jg.marketing.web;
import com.jg.marketing.DAO.Receiver;
import com.jg.marketing.repository.ReceiverRepo;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.dependency.StyleSheet;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.editor.Editor;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.converter.StringToIntegerConverter;
import com.vaadin.flow.data.validator.IntegerRangeValidator;
import com.vaadin.flow.data.validator.StringLengthValidator;
import com.vaadin.flow.router.Route;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Collection;
import java.util.Collections;
import java.util.WeakHashMap;
@Route("receivers")
@StyleSheet("/css/style.css")
public class ReceiverGui extends VerticalLayout {
private ReceiverRepo receiverRepo;
@Autowired
public ReceiverGui(ReceiverRepo receiverRepo) {
this.receiverRepo = receiverRepo;
// Receivers grid
Grid<Receiver> grid = new Grid<>(Receiver.class);
grid.setItems(receiverRepo.findAll());
grid.setColumns("id", "sapNumber", "score", "city", "postCode", "street", "streetNumber", "phoneNumber", "materials");
grid.getColumnByKey("id").setWidth("30px");
grid.getColumnByKey("score").setWidth("55px");
grid.getColumnByKey("city").setAutoWidth(true);
grid.getColumnByKey("postCode").setWidth("50px");
grid.getColumnByKey("street").setAutoWidth(true);
grid.getColumnByKey("streetNumber").setAutoWidth(true);
grid.getColumnByKey("phoneNumber").setAutoWidth(true);
// Grid editor
Binder<Receiver> binder = new Binder<>(Receiver.class);
Editor<Receiver> editor = grid.getEditor();
editor.setBinder(binder);
editor.setBuffered(true);
// Editor status message
Div validationStatus = new Div();
validationStatus.setId("validation");
// Add new Receiver horizontal layout
TextField textFieldSapNumber = new TextField("SAP", "wpisz numer");
binder.forField(textFieldSapNumber)
.withConverter(new StringToIntegerConverter("Niepoprawny numer"))
.withValidator(new IntegerRangeValidator("Niepoprawny zakres numeru SAP! 70000000 - 79999999", 70000000, 79999999))
.withStatusLabel(validationStatus)
.bind("sapNumber");
grid.getColumnByKey("sapNumber").setEditorComponent(textFieldSapNumber);
TextField textFieldScore = new TextField("Realizacja %", "np.: 99.99 ");
textFieldScore.setWidth("100px");
TextField textFieldCity = new TextField("Miasto", "wpisz miasto");
binder.forField(textFieldCity)
.withValidator(new StringLengthValidator("Wprowadź nazwe miasta o długości od 2 do 25 znaków", 2, 25))
.withStatusLabel(validationStatus)
.bind("city");
grid.getColumnByKey("city").setEditorComponent(textFieldCity);
TextField textFieldPostCode = new TextField("Kod pocztowy", "np.: 12-345");
textFieldPostCode.setWidth("120px");
binder.forField(textFieldPostCode)
.withValidator(new StringLengthValidator("Wprowadź kod rozdzielony myślnikiem wg. wzoru: 12-345", 6, 6))
.bind("postCode");
grid.getColumnByKey("postCode").setEditorComponent(textFieldPostCode);
// TODO PostCode validation
TextField textFieldStreet = new TextField("Ulica", "wpisz ulicę");
TextField textFieldStreetNumber = new TextField("Nr budynku", "np.: 125 B");
textFieldStreetNumber.setWidth("120px");
TextField textFieldPhoneNumber = new TextField("Nr kontaktowy", "podaj nr telefonu");
HorizontalLayout addNewReceiverSection = new HorizontalLayout(textFieldSapNumber, textFieldScore, textFieldCity, textFieldPostCode, textFieldStreet, textFieldStreetNumber, textFieldPhoneNumber);
// Add edit buttons column
Collection<Button> editButtons = Collections
.newSetFromMap(new WeakHashMap<>());
Grid.Column<Receiver> editorColumn = grid.addComponentColumn(receiver -> {
Button edit = new Button("Edytuj");
edit.addClassName("edit");
edit.addClickListener(e -> {
editor.editItem(receiver);
textFieldSapNumber.focus();
});
edit.setEnabled(!editor.isOpen());
editButtons.add(edit);
return edit;
});
editor.addOpenListener(e -> editButtons.stream()
.forEach(button -> button.setEnabled(!editor.isOpen()))
);
editor.addCloseListener(e -> editButtons.stream()
.forEach(button -> button.setEnabled(!editor.isOpen()))
);
Button save = new Button("Save", e -> editor.save());
save.addClassName("save");
Button cancel = new Button("Cancel", e -> editor.cancel());
cancel.addClassName("cancel");
// Add a keypress listener that listens for an escape key up event.
// Note! some browsers return key as Escape and some as Esc
grid.getElement().addEventListener("keyup", event -> editor.cancel())
.setFilter("event.key === 'Escape' || event.key === 'Esc'");
Div buttons = new Div(save, cancel);
editorColumn.setEditorComponent(buttons);
editor.addSaveListener(
event -> validationStatus.setText("Poprawnie zaktualizowano wpis"));
add(validationStatus, grid);
// Submit new receiver button
Button buttonAddReceiver = new Button("Dodaj", new Icon(VaadinIcon.PLUS));
buttonAddReceiver.addClickListener(buttonClickEvent -> {
final Receiver receiverToAdd
= new Receiver(Integer.parseInt(textFieldSapNumber.getValue()),
Double.parseDouble(textFieldScore.getValue()),
textFieldCity.getValue(),
textFieldPostCode.getValue(),
textFieldStreet.getValue(),
textFieldStreetNumber.getValue(),
textFieldPhoneNumber.getValue()
);
receiverRepo.save(receiverToAdd);
// Refresh grid data
grid.setItems(receiverRepo.findAll());
// Open notification
Notification notification = new Notification("Dodano nowego odbiorcę!", 3000);
notification.open();
});
add(addNewReceiverSection);
add(buttonAddReceiver);
add(grid);
}
}