Index of selected row in grid

Hi all,

I found some old discussion about this, but unfortunately no solution …

I need to know the index of the selected item in a grid, but in the click event I “only” receive the item itself (I’ve put it in quotes because that’s more than some other frameworks would provide …)

I want to create a “search navigator” (as you probably know from JIRA, for example: when you select an item in a search result, you get a detailed view, and in the top right you have the possibility to navigate through the results of the former search).

To properly initialize this navigator, I need not only the DataProvider the search was using at last (which is simple), but also the index of the selected item. I could find this index by iterating over the DataProvider, but it seems kind of weird to me to possibly trigger the backend only to find the index of an item which is definitely in memory.

I created the following workaround:

	private int findIndex(ItemClickEvent<E> cel) {
		try {
			DataCommunicator<E> dataCommunicator = grid.getDataCommunicator();
			var f = dataCommunicator.getClass().getDeclaredField("requestedRange");
			f.setAccessible(true);
			var v = (Range) f.get(dataCommunicator);
			for (int i = v.getStart(); i < v.getEnd(); i++) {
				var r = dataCommunicator.getItem(i);
				if (r.id().equals(cel.getItem().id())) {
					return i;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return -1;
	}

Of course … this is really bad … but it seems to work.

Is there some API I’ve missed? If not, if at least the requestedRange was publicly available, this would help … or in the optimum case, the index could be provided in the event?

Marcus.

1 Like

Why do you want to build that on the row index of an item in the grid? What happens, if someone sorts the grid in a different order for instance? Or when the amount of data changed (i.e. in a ticket system the list of open issues changes when something is closed)

I would strongly recommend you to use the id of the item instead or some other value, that is unique in its context (as most ticket systems do with their issue numbers) and base your functionality on that. You could for instance use that id then in the url.

1 Like

In case of in memory data, you should use DataView API for this. Here is some example

        GridListDataView<Item> dataView = grid.setItems(items);
        ...
        Optional<Integer> optionalIndex = dataView.getItemIndex(item);

The DataView applies the same filter and sorting that is currently visible in the Grid.

If you are using callback data provider, then you need to compute the index in your backend query using the same filter and sorting as is active in Grid.

I have a list view (results from some search query), and by clicking on an item in the list, I navigate to the detail view of this item.

In addition to the details, I want to display a navigator which allows to move to the previous/next search result (based on the list the detail view was called from), something like

    < 17/181 >

This navigator shall respect the results of the previous list view (sorting, filtering and amount of data).

The big part of the implementation is simple, but finding the starting point (“17” in the above example) is quite difficult.

Yes, it’s a CallbackDataProvider, but since the clicked item is obviously in memory, I want to avoid additional calls to the backend. My workaround proves that it could be possible :-)