Search code examples
javajquerygwtjsni

Calling Java function from within jQuery slider through JSNI


I have got the main class (say StockWatcher) call a JSNI to define a jQuery UI dialog within the body at page-load. The dialog is called within a JSNI function. On onModuleLoad, I do something like prepareUI();. The prepareUI JSNI runs as follows:

public void native prepareUI() /*-{
  $wnd.jQuery($doc).ready(function($) { 
    message = "<div id = 'message'>Don't do this...</div>
    $(message).appendTo("body");
    $( "#message" ).dialog({
            modal: true,
            buttons: {
                Ok: function() {
                    $( this ).dialog( "close" );
                }
            },
            close:function() {  [email protected]::doit()(); },
            autoOpen: true,
            show: {
            effect: "puff",
            duration: 500
            },
            hide: {
            effect: "explode",
            duration: 500
            }
        });
 });
}-*/;

This is followed by the doit() function, which is simple enough:

public void doit() {
  Window.alert("Foo");
}

But, on page-load, even though the dialog appears correctly, and even closes corrrectly on clicking the Ok button, the alert doesn't pop up (No error is shown in console). Can anyone tell me how to fix this? The class within which this is done is StockWatcher in the package com.google.gwt.sample.stockwatcher.client (imagine the default GWT StockWatcher package hierarchy).


Solution

  • Your problem is the this. When the function is called, this is not your StockWatcher class (it'll be your #message element). You have to use $.proxy or a simple var that = this at the top of your method. It's all about scoping.

    BTW, you should also wrap your function with $entry: it'll make sure a few things go well in GWT: exceptions are routed to the GWT.UncaughtExceptionHandler, and commands scheduled via Scheduler#scheduleEntry and Scheduler#scheduleFinally are correctly called.

    Example using $.proxy:

    var closeFn = $.proxy($entry(function() {
        [email protected]::doit()();
      }), this);
    $wnd.jQuery($doc).ready(function($) {
      …
      $( "#message" ).dialog({
        …
        close: closeFn,
    …    
    

    Example using var that = this:

    var that = this;
    $wnd.jQuery($doc).ready(function($) {
      …
      $( "#message" ).dialog({
        …
        close: $entry(function() { [email protected]::doit()(); }),
    …