I create simple grid with data from database:
BeanItemContainer<Customer> container = new BeanItemContainer<>(Customer.class, customerRepository.findAll());
Grid grid = new Grid(container);
To edit each row the button was created:
Button edit = new Button("Edit", clickEvent -> openWindow((Customer) grid.getSelectedRows().iterator().next()));
This open new window with edit form. After all changes accepted, I must manually refresh whole page to see modification on Grid. My question is:
How refresh only Grid after modification of any row entry?
And how save those modifications to database (maybe beanItemContainer could do it)?
It's a bug. Grid doesn't update itself after changes were done in underlying container nor has any reasonable method to refresh. There are several hacks around this issue i.e.
grid.clearSortOrder();
or
grid.setEditorEnabled(true);
grid.setEditorEnabled(false);
SSCCE:
TextField text = new TextField("Edit");
Grid grid;
BeanItemContainer<Customer> container;
@Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
container = new BeanItemContainer<>(Customer.class, Arrays.asList(new Customer("1"), new Customer("2")));
grid = new Grid(container);
Button open = new Button("open");
open.addClickListener(this :: openListener);
Button save = new Button("save");
save.addClickListener(this :: saveListener);
layout.addComponents(grid, open, save, text);
setContent(layout);
}
private void openListener(Button.ClickEvent clickEvent){
text.setValue(((Customer) (grid.getSelectedRow())).getName());
}
private void saveListener(Button.ClickEvent clickEvent){
Customer c = (Customer) grid.getSelectedRow();
c.setName(text.getValue());
grid.clearSortOrder();
}
Possible duplicate Update Grid with a fresh set of data, in Vaadin 7.4 app
With Vaadin 8, the following works to refresh the grid after rows have been added or removed or the underlying data has been changed:
grid.getDataProvider().refreshAll();
Since Vaadin 7.7.4 there is a refreshRows(Object ... itemIds)
and a refreshAllRows()
method in the grid: https://dev.vaadin.com/ticket/16765
I had to explicitly call grid.setItems()
after each call to saveListener
event to make my Vaadin 8.3 Grid refresh data inside the grid. It's strange that the visual grid state does not reflect edited values.
Scala implementation:
var advicesList : mutable.MutableList[Advice] = null
private def initGrid() = {
advicesList = mutable.MutableList(itmemsFromDB: _*)
setItems(advicesList.asJava)
getEditor.addSaveListener((event) => {
val bean = event.getBean
Notification.show("Saved value: " + bean)
// ==== RELOAD GRID ITEMS AFTER EDITION
val oldItemIdx = advicesList.indexOf(advicesList.filter(a => a.id == bean.id).head)
advicesList.update(oldItemIdx, bean)
event.getGrid.setItems(advicesList.asJava)
})
}
There is a way to solve the problem much better:
You have to get the BeanItem
from the container and pass this to your editor window. There you can change the bean itself by asscessing it hrough the BeanItem
s Properies
. This is a very manual work so I use instead always databindg of FieldGroup
- just call bind
(field, "propertyName"); where propertyName is the getter method without get and non capital letter.