You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 10 Next »

What ?

Since version 6.0 Wicket uses JQuery as a backing library for its Ajax functionality.

Why ?

The previous implementations of wicket-ajax.js and wicket-event.js were home baked solutions that 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.

Design and implementation

The new implementations (wicket-ajax-jquery.js and wicket-event-jquery.js) use JQuery internally but expose Wicket.** API similar to the previous version.

All Java components and behaviors should still use the Wicket.** API. This way if someday we decide to not use JQuery anymore we will have less work to do. Also if a user uses Dojo/YUI/ExtJS/... and prefer to not have JQuery in her application then she will be able to provide wicket-ajax-xyz.js implementation and replace the default one.

Table with renamed methods from the previous version

1.5

6.0

Wicket.fixEvent

Wicket.Event.fix

Wicket.stopEvent

Wicket.Event.stop

Wicket.show

Wicket.DOM.show

Wicket.showIncrementally

Wicket.DOM.showIncrementally

Wicket.hide

Wicket.DOM.hide

Wicket.hideIncrementally

Wicket.DOM.hideIncrementally

Wicket.decode

Wicket.Head.Contributor.decode

Wicket.ajaxGet, wicketAjaxGet

Wicket.Ajax.get

Wicket.ajaxPost, wicketAjaxPost

Wicket.Ajax.post

Wicket.submitForm

Wicket.Ajax.submitForm

Wicket.submitFormById

Wicket.Ajax.submitForm

Wicket.replaceOuterHtml

Wicket.DOM.replace

Wicket.Form.doSerialize

Wicket.Form.serializeForm

Link to jsdoc

TODO

Configuration

To replace any of the JavaScript files the user application may use:

MyApplication#init():

public void init() {
  super.init();

  IJavaScriptLibrarySettings jsSettings = getJavaScriptLibrarySettings();

  jsSettings.setBackingLibraryReference(DojoReference.class);

  jsSettings.setWicketEventReference(DojoWicketEventReference.class);
  
  jsSettings.setWicketAjaxReference(DojoWicketAjaxReference.class);

}

Since Wicket 6.0 ResourceReference can have dependencies and it is recommended to properly define the dependency chain between this classes.
See the code of org.apache.wicket.ajax.WicketAjaxJQueryResourceReference to see how the default JQuery based implementation does that.

If the user application needs to upgrade/downgrade to new/old version of JQuery then just the first line above is needed:

  getJavaScriptLibrarySettings().setBackingLibraryReference(AnotherVersionOfJQueryReference.class);

AjaxRequestAttributes

Each Ajax behavior and component can use o.a.w.ajax.attributes.AjaxRequestAttributes to configure how exactly the Ajax call should be executed and how its response should be handled. To do this use:

AnyAjaxComponent/AnyAjaxBehavior.java:

  protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
  {
      super.updateAjaxAttributes(AjaxRequestAttributes attributes);

      attributes.[set some attribute]();
  }

The available attributes are:

  • method - the request method to use (GET or POST)
  • multipart - whether form submittion should use content type: multipart/form-data. Implies POST method.
  • event names - a list of event names for which the Ajax call will be executed. For example: click, change, keyup, etc.
  • form id - the id of the form which should be submitted with this Ajax call
  • submitting component name - the input name of the component which submits the form
  • data type - what kind of data is expected in the response of the Ajax call
  • is wicket ajax response - a flag which indicates whether the response is <ajax-response> which is handled by wicket-ajax.js or custom response type which can be handled by application's code (e.g. in IAjaxCallListener's success handler)
  • preconditions - a list of preconditions which may abort the Ajax call. Return 'false' from any precondition to abort the call
  • channel - the name and type of the Ajax channel to use. Channels are used to queue the Ajax requests at the client side. See org.apache.wicket.ajax.AjaxChannel javadoc for more details.
  • ajax call listeners - see below for more information
  • extra parameters - a map of parameters which should be added to the query string/post data of the Ajax call
  • dynamic extra parameters - parameters which are calculated at the client side and added dynamically to the query string/post data of the Ajax call
  • request timeout - a timeout to about the request if there is no response
  • allow default - a flag which indicates whether to allow the default behavior of the HTML element which listens for the event. For example: clicking on Ajax checkbox should allow the default to actually check the box
  • async - a flag that indicates whether the Ajax call should be asynchronous or not
  • throttling settings - settings which define whether the Ajax call should be throttled and for how long. See org.apache.wicket.ajax.attributes.ThrottlingSettings

While constructing the JavaScript that will register the event listener for that Ajax component/behavior these settings are serialized to optimized JSON object which is passed as a parameter to Wicket.Ajax.(get|post|ajax) methods.
For example an AjaxLink contributes JavaScript similar to :

  Wicket.Ajax.get({"u":"the/url/to/the/link", "e": "click", "c":"linkId"});

Many of the attributes have default values which are not written in the JSON settings and they are initialized at the client side (i.e. wicket-ajax.js knows the defaults). The example above can be read as: when HTML element with id 'linkId' is clicked fire an Ajax call with Url 'the/url/to/the/link'.

Migration steps

o.a.w.ajax.IAjaxCallDecorator is replaced with o.a.w.ajax.attributes.IAjaxCallListener.

Since Wicket Ajax now register DOM events (like click, change, ...) instead of using inline attributes like onclick, onchange, ... there is no more a script to decorate. Instead the new implementation provides points to listen to:

  • before handler - executed before the fire of the Ajax call
  • after handler - executed after the fire of the Ajax call but before it returns (if the Ajax call is asynchronous)
  • success handler - executed on successful return of the Ajax call
  • failure handler - executed on unsuccessful return of the Ajax call
  • complete handler - executed on both successful and unsuccessful return

To use it do:
AnyAjaxComponent/AnyAjaxBehavior.java:

  protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
  {
      super.updateAjaxAttributes(AjaxRequestAttributes attributes);

      AjaxCallListener myAjaxCallListener = new AjaxCallListener() {

        @Override public CharSequence getBeforeHandler() { return "alert('I\'m executed before the firing of the Ajax call')"; }
      };
      attributes.getAjaxCallListeners().add(myAjaxCallListener);
  }

An Ajax request can have 0 or more IAjaxCallListener's.
o.a.w.ajax.attributes.AjaxCallListener is an adapter of IAjaxCallListener that implements all methods with noop bodies. If the body returns null or empty string then it is discarded.

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.

Example:

    Wicket.Event.subscribe('/ajax/call/failure', function(jqEvent, errorThrown, attributes, jqXHR, 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. This event is not the event that causes the Ajax call. The one that caused the Ajax call is 'attrs.event'.

Automatically migrated attributes.

Some of the attributes are available from the previous versions of Wicket as an overridable methods in AbstractDefaultAjaxBehavior. These methods are marked as deprecated and will be removed in Wicket 7.0 and for now Wicket automatically translates them into AjaxRequestAttributes.
These methods are:

  • org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#getPreconditionScript()
  • org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#getSuccessScript()
  • org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#getFailureScript()
  • org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#getChannel()

It is recommended to override org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#updateAjaxAttributes(AjaxRequestAttributes) and configure those directly in the passed 'attributes'.

Tests for the client side Wicket Ajax functionality

At ajax.js you may see the currently available JavaScript unit tests that we have for the Ajax functionality in wicket-ajax.js

  • No labels