Vaadin 8 Grid: Unable to re-select a row

The client side Grid is not seeing calls to select a row:

selectionModel.select(bean);

where selectionModel is a SingleSelectionModel and bean is an instance of Mybean.

Here’s what is happening, verified by markers in the code:

  1. User selects a row,
  2. The selection listener performs some logic, which includes a dataProvider refreshAll(),
  3. The DataProvider listener refers to the old selected bean to find the corresponding new bean and makes the re-selection based on that. The selection listener is coded to (correctly) ignore this system-generated re-selection to avoid an infinite loop.

According to the client side trace:

  1. The Grid receives the initial selection request.
  2. The Grid’s old rows are replaced with new rows following the fetching of new data
  3. … that’s it. The re-selection statement is not heard by the client. Traces indicate that the
selectionModel.select(bean);

code is running as expected and contains the correct bean. There are no further calls to the selection listener so I don’t suspect that the re-selection is working then being de-selected.

The Grid shows no selection, but there is a selection. The selection listener logic is correctly run. Clicking on the same row again (which is not highlighted blue) results in another selection of that row, rather than a de-selection.

Any ideas? There is a similar-sounding
discussion here
. None of the clues there work for me in Vaadin 8.

I wonder if the problem is here in this excerpt from com.vaadin.ui.components.grid.SingleSelectionModelImpl.java?

The idea in this section seems to be that if the selection is unchanged, there is nothing to do, so return. But in fact, the selection is unchanged but the underlying data has changed, so the unchanged selection should be applied to the new grid rows - but it is not. That is consistent with the failure to re-select that I’m seeing in my project.

/**
* Sets the selection based on server API call. Does nothing if the
* selection would not change; otherwise updates the selection and fires a
* selection change event with {@code isUserOriginated == false}.
*
* @param item
* the item to select or {@code null} to clear selection
*/
protected void setSelectedFromServer(T item) {
// TODO creates a key if item not in data provider
String key = itemToKey(item);
if (isSelected(item) || isKeySelected(key)) {
return;
}
T oldSelection = this.getSelectedItem()
.orElse(asSingleSelect().getEmptyValue());
doSetSelectedKey(key);
fireEvent(new SingleSelectionEvent<>(getGrid(), asSingleSelect(),
oldSelection, false));
}
/**
* Returns the communication key assigned to the given item.
*
* @param item
* the item whose key to return
* @return the assigned key
*/
protected String itemToKey(T item) {
if (item == null) {
return null;
} else {
// TODO creates a key if item not in data provider
return getGrid().getDataCommunicator().getKeyMapper().key(item);
}
}

Maybe this part of code should be eliminated?

if (isSelected(item) || isKeySelected(key)) {
return;
}

Or replaced with someting like:

if ((isSelected(item) || isKeySelected(key)) && dataIsUnchanged()) {
return;
}

If change information about the underlying data is available…

Hi Steve, did you ever resolve the " Keyboard navigation - Cell Focus and Item Activation" challenge?

I am seeking to accomplish the same: to navigate the Vaadin Grid using arrow key up or arrow key down, while the focus is updated and reflected in the FORM to match the currently selected GRID row.

I do not think so… the issue of keyboard navigation of an application has always been so basic, I find it odd that special effort would be needed with a Vaadin Grid.

Please, if you have time, may you please view this post:
https://vaadin.com/forum#!/thread/15820861

dataSQL, I went through several iterations of overhauling my internal data model which eliminated my problem. Your focus problem sounds different. Could it be solved using a focus listener?

im having the same problem… did you fixed it?

Any updates on this?

I use Maps, specifically HashMap<String, Object> as the basis of data for my grids. In other words, they are my “beans”. In order for selection and single row refresh operations to work properly, it was necessary to create a custom Map implementation, extending HashMap<String, Object> that overrides hashCode and equals so that Grid can distinguish old rows from new rows.