Archive

Archive for February, 2012

Page onload Ajax request in Wicket

February 22nd, 2012 Nick 1 comment

A new requirement arrived this week to display a load of statistics on the main page of the application. Simple enough, except that the collection of these statistics from the database took an unacceptably long time to load. As this was the main page, every user had to wait for the statistics to load after logging in before they could navigate to the page they wanted. Unfortunately simple caching wasn’t an option as the data must be up-to-date and more elaborate caching techniques were off the cards due to time restrictions on the implementation effort.

The solution I came up with was to render the page without the statistics but instead showing a message saying “Statistics loading, please wait…”. Once the page loaded, an Ajax request was fired which generated the statistics and replaced the message. Now the page loaded immediately and users did not have to wait for the statistics to load before navigating to another page.

However, implementing this in Wicket was not so straightforward, so I thought I’d write up my solution.

The first step was to create an implementation of AjaxEventBehavior which created a new instance of the statistics panel to replace the “Loading…” message component. So far all pretty basic.

AjaxEventBehavior loader = new AjaxEventBehavior("onload") {
	//...

Getting this Ajax event to fire on page load was a bit trickier. The normal way is to attach a Javascript event to the tag, or specify its onload attribute. Luckily, there is a way to do this in Wicket. All the pages in the application extend from a base class which itself extends Page. This base class provides standard layout so that all the pages in the application look similar, share the same HTML headers and so on. The associated HTML of this base class defined the tag, so in order to be able to access it in Wicket I added a wicket id, something like this:

<body wicket:id="body">

Great, so I can access the body tag – but now I’ve broken the hierarchy, all the components now need to be added to the body tag, not the page. Rather than rework the entire page class, it is possible to set the body element to be transparent in the hierarchy:

        body = new WebMarkupContainer("body"){
            @Override
            public boolean isTransparentResolver()
            {
                return true;
            }
        };

        add(body);

Now all I had to do was create a protected getter method to allow access to the body element and now I could add the Ajax behaviour from the main page.

Categories: Java Tags: , ,