Tuesday, June 30, 2009

Apache Wicket - How to run and get response from JavaScript

If you dont know what is Wicket - you are realling missing something. It is a b'ful framework from Apache which will make our life very much easier when doing web application development.
You can read more about Apache Wicket here

Here let us check how to invoke Javascript from a Wicket component and how receive/handle response. Assume the requirement is having a webpage where we will load some control using Javascript(For example - Google Earth ;) ) , and once the javascript execution is completed the page should do something.

01 public class MyPage extends WebPage {
02 /**
03 * Def constructor.
04
05 */

06 public MyPage() {
07 //
08 // Create and add a panel.
09 final JSPanel panel = new JSPanel("jsPanel");
10 panel.setOutputMarkupId(true);
11 add(panel);
12 }

Here we are creating a webpage and adding a panel to that. The panel is the place where we will
display the GoogleEarth through loading JavaScript.

But before going to the panel let us check how to get a call back from the JavaScript.
For acheiving this we will add an AjaxBehavior to the panel

01 public MyPage() {
02 ...
03 //
04 // Add an Ajax behaviour, this will be called by the javaScript
05 // when the streaming is completed.

06
final AbstractDefaultAjaxBehavior behave = new AbstractDefaultAjaxBehavior() {
07 protected void respond(final AjaxRequestTarget target) {
08 //
09 // Read the parameters send by JavaScript
10 Map map = ((WebRequestCycle)RequestCycle.get()).getRequest().getParameterMap();
11 Set keys = map.keySet();
12 Iterator it = keys.iterator();
13 while(it.hasNext()) {
14 String key = (String) it.next();
15 String[] value = (String[]) map.get(key);
16 }
17 }
18 };
19 panel.add(behave);
20 }


Curresponding html files are simple enough.

Now lets look at the JSPanel. Here we need to call the javascrip onLoad of the page. This is acheived through RenderHead method.


01 public class JSPanel extends Panel implements IHeaderContributor {
02 /**
03 * Def constructor.
04
05 */

06 public GEPanel(String id) {
07 super(id);
08 }

09
public void renderHead(IHeaderResponse response) {
10 //
11 // Check the behavior to get the callback URL
12 List list = getBehaviors();
13 String url = "";
14 if (list != null && list.size() > 0) {
15 AbstractDefaultAjaxBehavior beh = (AbstractDefaultAjaxBehavior) list.get(0);
16 url = beh.getCallbackUrl().toString();
17 }
18 String methodCall = "Your JS Method call";
19 response.renderOnLoadJavascript(methodCall);
20 }
21 }


Lets look at the relevant javascript now

function init(urlVal) {
url = urlVal;
//
//Create an instance of GE.
google.earth.createInstance("map3d", initCallback, failureCallback);
}

function initCallback(object) {
//
// Show GE and move camera to decired location.
ge = object;
ge.getWindow().setVisibility(true);
var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
...
ge.getView().setAbstractView(lookAt);
...
//
// Make a call to the wicket callback url from here
var arg = "&key=" + value;
var wcall = wicketAjaxGet(url + arg , function() { }, function() { });
}

That is it. Let me know if you need the complete sample code for this.

Java code displayed as html here is using a tool HTML4Java, you can check it here http://www.toolbuddy.org/html4java.htm








2 comments: