Wicket Ajax Hooks
In Wicket if we want to do something before and after every ajax call
we would do that by registering the wicket ajax callbacks as follows.
// check whether the page contains any ajax links
if ( Wicket . Ajax ) {
Wicket . Ajax . registerPreCallHandler ( preAjaxHandler );
Wicket . Ajax . registerPostCallHandler ( successHandler );
Wicket . Ajax . registerFailureHandler ( failureHandler );
}
Problem
Most of the time we need to update or add event handlers or do some
initialization on the newly added DOMs. But we don’t know Which DOMs
are updated by wicket.wicket doesn’t call our post handlers with the
list of newly added DOMs.
Solution
It is very easy to do it by ourself.Ok let start by creating a Ajax
event Handler
MyApp . Ajax = {
// contains the list of handler to be invoked
// after ajax response
postAjaxHandlers : [],
// contains the ids of the changed elements
changedDomIds : [],
// registers the post ajax handles
registerPostAjax : function ( fn ) {
this . postAjaxHandlers . push ( fn );
},
// this should be invoked by the the wicket
handle : function ( changed ) {
this . changedDomIds = changed ;
},
// fires the post ajax event with collection of updated dom
firePostHandlers : function () {
var that = MyApp . Ajax ;
// fire the hanldler only if there is updated dom ids
if ( ! that . changedDomIds . length == 0 ) {
var selector = '' ;
$ . each ( that . changedDomIds , function () {
selector += ' # ' + this + ' , ' ;
});
var elements = $ ( selector );
// invoke the handlers
$ . each ( that . postAjaxHandlers , function () {
this ( elements );
});
// clear the ids
that . changedDomIds = [];
}
}
};
MyApp . Ajax . registerPostAjax ( function ( changed$ ){
// do you work here
changed$ . find ( ' mydiv.myclass ' );
});
// register the handlers
$ ( document ). ready ( function () {
if ( Wicket . Ajax ) {
Wicket . Ajax . registerPostCallHandler ( MyApp . Ajax . firePostHandlers );
}
});
Now we finished our client side work. Ok let start our server side work.
Add this function to your base class;
/**
* fires a event with the collection of all the updated dom elements after
* the wicket ajax response. To subscribe the event call the
* <code>MyApp.Ajax.registerPostAjax</code>. Your callback function
* will be called with a jQuery Wrapped set of all the update dom as the
* first argument.
*
* NOTE: call this only once after all the components are added to the
* target
*
*
* @param target
* ajax target
*/
public void firePostAjaxUpdateEvent ( final AjaxRequestTarget target )
{
final StringBuffer script = new StringBuffer ( " MyApp.Ajax.handle([" );
for ( final Component component : target . getComponents ())
{
script . append ( "\"" + component . getMarkupId () + "\"," );
}
script . append ( "])" );
target . getHeaderResponse (). renderOnDomReadyJavascript ( script . toString ());
}
Now if we want to intialize something on the newly added DOMs simply
we can call this method and a event with the list of updated DOMs will
be fired on the client side.
@Override
protected void onSubmit ( final AjaxRequestTarget target )
{
// add all the components
firePostAjaxUpdateEvent ( target );
}
Your comments are welcome.