i hava a lazy Grid with items and dataprovider. When i click into an item and go back ia Browser return button, i want to jump to the correct page & position.
I have tried to save this data temporaily in the session an read it in beforeenter. But anyhow it wont work. Does anyone has successfully implemented this kind of feature and could guide me in the right direction?
This happens because the scroll position is not preserved when DOM elements are re-created.
One way around this is to preserve DOM elements e.g. by using the new MasterDetailLayout. Another possibility is to keep track of which item was selected before and then use scrollToItem when returning.
i have tried it but it didnt work. I think i invoked it to early (should be after dataprovider.refreshAll() probably. Need to give it another try. Thank you!
The object in grid must override egauls () and hash() to work?
i must use entityGrid.getLazyDataView().setItemIndexProvider right? Got an issue, when i scroll down the page and up and open some “cards” after 5 or 6 “Browser” backs, the index is wrong and it scrolls to a incorrect entry. Looks like the index is incorrect.
When i click a Card Item in Grid i add the index to the browser session:
Code
public OverviewCard(OrderEntity orderEntity, int index, AtomicInteger indexCounter) {
addClassNames("order-card", LumoUtility.Display.FLEX, LumoUtility.FlexWrap.WRAP);
setJustifyContentMode(JustifyContentMode.EVENLY);
setPadding(true);
setSpacing(true);
createOrderCard(orderEntity);
addClickListener(event -> {
UI.getCurrent().getPage().executeJs("sessionStorage.setItem($0, $1);", "selectedItem", orderEntity.getId());
UI.getCurrent().getPage().executeJs("sessionStorage.setItem($0, $1);", "selectedItemIndex", index);
UI.getCurrent().getPage().executeJs("sessionStorage.setItem($0, $1);", "selectedItemOffset", indexCounter.get());
//Navigate to the URL which routes to the corresponding DetailsItem
);
});
}
when i come back into the overview, i read the index etc vfrom session, that works some rounds but like mentioned after 5 or 6 tests, it scrolls to a false index
Person person = new Person(357, "Person 357");
Stream<Person> items = grid.getGenericDataView().getItems();
AtomicInteger i = new AtomicInteger();
int index = items.peek(v -> i.incrementAndGet()).anyMatch(itm -> itm.equals(person)) ? i.get() - 1 : -1;
grid.scrollToIndex(index);
grid.select(person);
I would like to summon @Leif to this discussion combined with the following comment:
We currently have an open VS-(number not with me) about a requirement to re-select/scroll-to a Combobox value after re-opening. This Grid example looks like the exact same use-case where a flow solution / improvement on the data provider API might be a good fit.
The point of that additional query is performance with large data sets. If you have 100000 items in the Grid and want to find the index of an item that is at the very end, then you’d end up loading all of those items into memory (or doing n + 1 requests to avoid loading the very last one) if you don’t have that additional query. The typical query is also not efficient if it has to do a full table scan in the database but that’s still way better than the in-memory approach that scans the whole database while also allocating all those objects on the Java heap.
(And I suspect Simon’s hack could be made slightly more pretty by using something like items.takeWhile(item -> !item.equals(person)).count(); to avoid the AtomicInteger)
What might be useful in both cases could be a feature to get the current scroll position out of the component before navigating away so that you can easily restore that exact position when returning without any of the indirections discussed here. The main challenge there is that you don’t want to send all those intermediate scroll events to the server but somehow only the result of the very last one.
One generic framework mechanism for that could be a “scroll preserver” that allows you to associate a unique id for some scrollable container. There would then be a client-side scroll listener that stores the scroll position in a client-side map (potentially configurable whether that’s in-memory, session storage, or local storage) and then using the same unique id when returning to automatically restore the scroll position.
Another potential generic mechanism could be a client-side “before detach” listener that can extract selected state right before a component is detached and send that to server-side application logic to use for any purpse.