Wicket in Action

A comprehensive guide for Java developers building Wicket-based web applications

Wicket 6 JavaScript improvements

A major rework of the internals of the core Wicket JavaScript libraries has been done for Wicket 6. The good news is the client APIs are mostly the same and the application developers will not need to change their applications.

Event registration

Until version 1.5.x attaching an Ajax event behavior to a component would lead to addition of an inline attribute to the markup of this component. For example the produced markup for an AjaxLink is similar to:

<a id="linkId" onclick="wicketAjaxGet('some/url')">Link</a>

In Wicket 6 JavaScript event registration is being used instead. For example the above becomes:

<head>
  ...
  <script>
    Wicket.Event.add(window, 'domready', function(event) {
      Wicket.Ajax.get({'u': 'some/url', 'c': 'linkId', 'e': 'click'}));
      // ... more event registrations and onDomReady scripts
    });
  </script>
</head>
...
<a id="linkId">Link</a>

The benefit is that the event registrations for all elements are done in one place – the page header and your markup elements are not cluttered with extra attributes. Also the generated code for the event registration is much shorter than the one produced in the earlier versions.

jQuery as backing library

The previous implementations of wicket-ajax.js and wicket-event.js were home baked solutions which worked well but also suffered from the differences in the browsers. Often users complained that some functionality doesn’t work on particular version of particular browser. That’s why the Wicket team chose to use JQuery to deal with browser inconsistencies and leave us to do our business logic.

All Java components and behaviors still use the Wicket.** APIs so if an application already uses another big JavaScript library and adding jQuery is not an option then the developer of this application will be able to provide implementation of wicket-event.js and wicket-ajax.js based on her favorite JavaScript library.
To do it the developer should use the new IJavaScriptLibrarySettings:

MyApplication#init():

 
public void init() {
  super.init();
 
  IJavaScriptLibrarySettings jsSettings = getJavaScriptLibrarySettings();
 
  jsSettings.setBackingLibraryReference(new DojoResourceReference());
 
  jsSettings.setWicketEventReference(new DojoWicketEventResourceReference());
 
  jsSettings.setWicketAjaxReference(new DojoWicketAjaxResourceReference());
 
}

Ajax request attributes

The main change in the Java code is the introduction of AjaxRequestAttributes in Ajax behaviors API.
AjaxRequestAttributes can be used to configure how exactly the Ajax call should be executed and how its response should be processed. To do this use:

AnyAjaxComponent/AnyAjaxBehavior.java:

  @Override
  protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
  {
      super.updateAjaxAttributes(attributes);
 
      attributes.setSomeAttribute();
  }

This way the developer can specify whether the Ajax call should use GET or POST method, whether to submit a form, on what JavaScript events to listen to, etc. For a full list of the available attributes see the new Wiki page. Most of the attributes have default values and they may be omitted in the generated JavaScript code.

Ajax call listeners

Because of the usage of event registration there is no need of IAjaxCallDecorator because there is no script to decorate anymore. The same functionality can be achieved with the new IAjaxCallListener. It provides the means to register JavaScript listeners which are being called during the Ajax call execution. A listener may provide a precondition which may cancel completely the Ajax call when evaluated to false, a before handler – executed right after the successful pass of the preconditions, an after handler – executed right after the make of the Ajax call, a success handler – executed on successful return of the Ajax call, a failure handler – executed when the Ajax call fails for some reason, and a complete handler which is executed after the success/failure handlers no matter what.

To register an AjaxCallListener do something like:

  @Override
  protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
  {
      super.updateAjaxAttributes(AjaxRequestAttributes attributes);
 
      IAjaxCallListener listener = new IAjaxCallListener()
      {
        @Override
        public CharSequence getBeforeHandler(Component c) { return handler; }
        .....
      };
 
      attributes.getAjaxCallListeners().add(listener);
  }

In the example above the returned handler could be any instance of CharSequence. If it is an instance of JsonFunction then it will be written as is, otherwise Wicket will assume that the text is just the body of a JavaScript function and will wrap it in JsonFunction for you. The benefit of using JsonFunction is that it generates JSON with function as a value. This is non-valid JSON but this way there is no need to use eval() in the browser and the execution of the handlers is faster.

Global Ajax call listeners

IAjaxCallListener’s can be used to listen for the lifecycle of an Ajax call for a specific component. If the user application needs to listen for all Ajax calls then it may subscribe to the following topics:

  • /ajax/call/before
  • /ajax/call/after
  • /ajax/call/success
  • /ajax/call/failure
  • /ajax/call/complete

Those replaces the old Wicket.Ajax.(registerPreCallHandler|registerPostCallHandler|registerFailureHandler) methods and uses publish/subscribe mechanism.

Example (JavaScript):

    Wicket.Event.subscribe('/ajax/call/failure', function(jqEvent, attributes, jqXHR, errorThrown, textStatus) {
      // do something when an Ajax call fails
    });

All global listeners receive the same arguments as the respective IAjaxCallListener handler plus jQuery.Event that is passed by the PubSub system.

Demo application

At Martin Grigorov’s GitHub repository you may find a simple demo application that shows some of the new features.
The application provides a custom AjaxButton (HandlebarsButton) that uses:

  • org.apache.wicket.ajax.attributes.AjaxRequestAttributes#setWicketAjaxResponse(false) – tells Wicket.Ajax to not try to process the returned Ajax response. The response is custom JSON which will be processed by a custom success handler
  • org.apache.wicket.ajax.attributes.AjaxRequestAttributes#setDataType(“json”) – a hint to Wicket.Ajax that the response is JSON and it will try to parse it for us, so your success handler can use it as JavaScript object directly
  • usage of JsonFunction as success handler – this way the application needs to provide the complete code of a JavaScript function that will handle the success case
  • usage of plain Strings with the function bodies for the precondition, before and complete handlers – Wicket will wrap them in JsonFunction for you
  • shows how to suppress the execution of AjaxRequestHandler – there is no need of it since we return custom JSON response

The application itself just updates a POJO (an article) at the server side and serializes it to JSON which is used at the client side to be rendered with the help of Handlebars JavaScript library.

More

More complete documentation may be found at the Wiki. Feel free to contribute to make it better. Just create an account and edit it!

With this book, Wicket will become the greatest territory the Dutch have settled since Manhattan.

Nathan Hamblen
Senior Software Engineer, Teachscape Inc.

This is the complete and authoritative guide to Wicket, written and reviewed by the core members of the Apache Wicket team. If there's anything you want to know about Wicket, you are sure to find it in this book.

Jonathan Locke
Founder and Architect of Apache Wicket, Foreword Wicket in Action

Without question, Wicket in Action... is the be-all and end-all when it comes to Wicket.

Geertjan Wielenga, Wicket Netbeans Plugin Author

The tutorial and conversational tone of the writing makes the book very approachable.

Nick Heudecker
System Mobile

Loved the sample application—it tied everything together.

Phil Hanna
Senior Software Developer, SAS Institute

The essential guide for learning and using Wicket.

Erik van Oosten
Lead programmer and Project Manager, JTeam

Finally, the Web Framework of web frameworks, Apache Wicket, now has a bible of its own.

Per Ejeklint
Senior Software Architect, Heimore group

Wicket is an innovative evolution of the MVC programming with simple roots, but without a primer such as this, it can be more challenging than it needs to be.

Brian Topping
Founder, Bill2 Inc.

Wicket In Action glues the areas of web development with Apache Wicket together and gives a great overview of Apache Wicket...it will make a great compendium.

Nino Martinez Wael
Java Specialist, Jayway Denmark