Archive

Posts Tagged ‘wicket’

Page onload Ajax request in Wicket

February 22nd, 2012 Nick No comments

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: , ,

Javascript: Exception thrown and not caught

May 14th, 2011 Nick No comments

I recently started getting this Javascript error message on every page in my application:

Exception thrown and not caught

Interestingly, I only got this message in Internet Explorer (IE7) and only on the first page view after clearing my temporary internet files (cache). If I refreshed the page, the error was gone and only reappeared when I cleared my browser cache – again disappearing after a page refresh.

My suspicion was that some Javascript in the HTML was trying to call a function or a method on an object that was declared in an external Javascript file, crucially before that external file had loaded from the server. This would explain the fact that the error disappeared after a page refresh, as the external file would already be available from the browser cache.

The solution was simple – I wrapped the Javascript that was in the HTML file using jQuery’s $(document).ready() function and the problem was solved.

Interesting note for Wicket users:

My application is built in Wicket and I embed the Javascript into the HTML response using AbstractBehavior.renderHead(IHeaderResponse response). Initially I used response.renderOnDomReadyJavascript(String javascript) which executed the Javascript once the DOM was ready but before the external Javascript dependencies were loaded. My first attempt to fix this was to used response.renderOnLoadJavascript(String javascript) which, as the JavaDoc states, executes the Javascript after the the entire page is loaded. This worked fine, except when the behavior was applied to components rendered in an Ajax response, as of course there was no page load event when the ajax request completed.

My solution was to move back to using response.renderOnDomReadyJavascript(String javascript) and, as stated above, wrap my Javascript in jQuery’s $(document).ready() function.

Categories: Javascript Tags: , ,