Vaadin - Refresh grid after row modification
Asked Answered
S

5

10

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)?

Semiannual answered 6/8, 2015 at 16:44 Comment(1)
See similar Question but for Vaadin 8 instead of 7.Bloodline
A
10

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

Arthrospore answered 7/8, 2015 at 7:31 Comment(2)
Thank you very much. Your suggestion with clearSortOrder() works perfectly. Moreover for anybody who wants refresh only one row, there are some hints: Vaadin ForumSemiannual
If this is a bug, do you have the related Vaadin bug tracker number/link?Pyroelectric
G
12

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();
Graph answered 4/4, 2017 at 15:0 Comment(3)
Unfortunately this does not work in Vaadin 8. I need to setItems explicitly each time.Brad
@Brad if you set the data with setItems() to begin with, then yes since that's creates a DataProvider that wraps the list of items and so you need to update the items expliitly.Octane
@Brad but if you use a DataProvider that dynamically fetches data from a data store (e.g., a RDBMS) then the refreshAll() method works as advertised.Octane
A
10

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

Arthrospore answered 7/8, 2015 at 7:31 Comment(2)
Thank you very much. Your suggestion with clearSortOrder() works perfectly. Moreover for anybody who wants refresh only one row, there are some hints: Vaadin ForumSemiannual
If this is a bug, do you have the related Vaadin bug tracker number/link?Pyroelectric
S
1

Since Vaadin 7.7.4 there is a refreshRows(Object ... itemIds) and a refreshAllRows() method in the grid: https://dev.vaadin.com/ticket/16765

Slaver answered 24/11, 2016 at 9:0 Comment(4)
it is this method, but does nothing (Vaadin 7.7.9)Morelli
It used to work when I posted this answer (almost a year ago). If I were you I would check if the data is up to date in the container.Slaver
When the Grid is disabled, and rows are added or modified refreshAllRows() doesn't work, but clearSortOrder() doesMorelli
Do these guys even have control over their api. Wtf for refreshing a table. You should just give it a list of items and it should render it, how hard can it be. Forcably working with Vaadin for work and I hate it. Have been doing web dev for 15 years and never had to deal with this crap.Belton
C
0

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)
  })
}
Czardom answered 23/1, 2018 at 12:54 Comment(0)
E
0

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 BeanItems 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.

Embrocate answered 11/11, 2018 at 14:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.