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

jsosnowski
  • 1,560
  • 3
  • 26
  • 56

5 Answers5

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();
Harald Hetzner
  • 171
  • 1
  • 4
  • 3
    Unfortunately this does not work in Vaadin 8. I need to setItems explicitly each time. – Aubergine May 29 '17 at 22:58
  • 2
    @Aubergine 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. – sofend Jun 15 '17 at 23:27
  • 1
    @Aubergine 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. – sofend Jun 15 '17 at 23:28
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

Community
  • 1
  • 1
kukis
  • 4,489
  • 6
  • 27
  • 50
  • Thank you very much. Your suggestion with `clearSortOrder()` works perfectly. Moreover for anybody who wants refresh only one row, there are some hints: [Vaadin Forum](https://vaadin.com/forum/#!/thread/9319379/9334479) – jsosnowski Aug 10 '15 at 09:17
  • If this is a bug, do you have the related Vaadin bug tracker number/link? – Dominic Jul 22 '16 at 08:51
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

Pere
  • 1,068
  • 12
  • 20
user1411778
  • 461
  • 1
  • 5
  • 12
  • it is this method, but does nothing (Vaadin 7.7.9) – FiruzzZ Aug 30 '17 at 16:51
  • 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. – user1411778 Sep 01 '17 at 08:57
  • When the Grid is **disabled**, and rows are added or modified **refreshAllRows()** doesn't work, but **clearSortOrder()** does – FiruzzZ Apr 19 '18 at 13:55
  • 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. – html_programmer Sep 07 '21 at 23:21
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)
  })
}
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.

Veselin
  • 197
  • 2
  • 12