0

I've already tried to find anything about that problem but I guess I either was not sure how to shortly describe the problem to find a solution or nobody else had that before which I can't think of. Maybe my thinking is wrong, too.

I have a stateless wicket 1.6 form with an ajax supporting panel (WebMarkupContainer with output id). The panel holds a dataview with paging navigator. The dataview itself is filled by a DataProvider.

The panel shows some entries from the database and below that is the navigator. by clicking any page on the navigator, the panel is refreshed (ajax) and shows content from that page. The page itself is not re-rendered by the browser.

When I now leave the page by navigating to another internal page (so basically when leaving the dataview-panel-page in any way) to open a detail page or so and then return to that dataview-page the navigator is resetted (because it's stateless I guess). The navigator can't remember which page to show and begins at the top of the first page again.

The question is: How can I solve this? I would like to i.ex. navigate to page 2 and then temporary leave the page for another internal page. When returning I want to be on page 2, focussed on the record where I clicked the link to "details" before. This also happens when I just open a new page in a new Browser tab.

Thank you!

Here's some code:

    final WebMarkupContainer gamesPanel = new AjaxContainer("gamesPanel");
    final DataView<Game> dataView =
            new GameDataView("gameOverview", targetCurrencyModel, searchTextModel, gameFilterModel,
                    new GameDataProvider(searchTextModel, gameFilterModel, targetCurrencyModel));
    dataView.setItemsPerPage(ITEMS_PER_PAGE);
    gamesPanel.add(dataView);

    final XNPagingNavigator navigator = new XNPagingNavigator("navigator", dataView);
    navigator.setOutputMarkupId(true);
    add(navigator);

You guys can try what I mean: The page I'm talking about is http://www.xbox-now.de. Just navigate to page 2, then click on details and return to main page.

Hoax
  • 93
  • 2
  • 9

3 Answers3

0

I think you might use History API to push a new state when you click on navigation bar. In the new URL for the state you can include a parameter that indicates the index of the current navigator page. You can customize your AJAX link in order to perform this operations when user click on it.

For more details on History API see Updating address bar with new URL without hash or reloading the page

Community
  • 1
  • 1
Andrea Del Bene
  • 2,521
  • 1
  • 15
  • 20
0

I solved this in the NoWicket framework by introducing a model aware page cache which reuses page instances when hashcode/equals matches in the page model. You can see the implementation in the GitHub repo, try this implementation of the IPageFactory wrapper as a starting point, but it is more code involved there, just check out the code, debug the example and navigate the code to understand it better in order to apply it to your application. See your use case in action by trying this data table example in the documentation website (which you can also debug locally): http://invesdwin.de/nowicket/ajaxdatatable

Try changing the paging index, navigate to a different page and navigate back to the data table example page. You will still see the paging index that you left there.

subes
  • 1,832
  • 5
  • 22
  • 28
0

Thank you guys for your replies. I've done it now another way. Used the base code from here and modified it in some ways. Added some nice css AttributeModifiers to indicate the actual page:

item.add(new AttributeModifier("class", new PageLinkCssModel(pageable, pageIndex, "active")));

Then I modified some code to add or reset the page parameter, that it's 1) used only once and 2) keeps all the actual page parameters which were there before adding own ones. So I am just appending the page number now. This way I can keep my initially mount path like www.foo.bar/path/path/path. Complete URL would now look like: www.foo.bar/path/path?page=123.

To pass my entered page (i.e. page=5) to the data provider I just had to override the providers iterator. It should start with the page I entered. Due to the ugly generated navigator URLs (which are extremly bad for SEO) I now have nice looking urls which are working independently what wasn't possible before. And that's also the reason why I could not get back to the correct page. The navigator URL was not lookup-able by wicket.

new DataView<GamePrice>("gamePriceOverview", new GameDetailDataProvider(gameId, targetRegion) {
                @Override
                public Iterator<GamePrice> iterator(final long first, final long count) {
                    return super.iterator(ITEMS_PER_PAGE * getCurrentPage(), count);
                }

getCurrentPage() comes from the base template and gets the actual page number entered (if one is entered):

public long getCurrentPage() {
    // -1 weil zero based
    return getRequest().getQueryParameters().getParameterValue("page").toString() != null
            ? (getRequest().getQueryParameters().getParameterValue("page").toLong() - 1)
            : 0;
}

So instead of having ugly SEO-unfriendly URLs which are also not compatible to work independant (directly enter the generated url) I now have the same URL I expect with an added page-parameter.

URL now would looks like: http://localhost:8080/game/4249/de/doom-preorder?page=2

URL before was: localhost:8080/game/4249/DE/doom-preorder?0-1.ILinkListener-gamePrices-navigator-navigation-2-pageLink

If I now go back from the detail page to the main index with active "Bookmarkable-Navigator", I correctly come back to the page and position where I left it (because of bookmarkable page links).

That's how I achieved this problem with a nice bonus: User- and SEO-friendly URLs.

Hoax
  • 93
  • 2
  • 9