0

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() {  this.@com.google.gwt.sample.stockwatcher.client.StockWatcher::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).

SexyBeast
  • 7,913
  • 28
  • 108
  • 196
  • Same issue as http://stackoverflow.com/questions/15275087/gwt-calling-instance-method-from-external-javascript (and you should use `$entry` too) – Thomas Broyer Mar 07 '13 at 15:39
  • tried replacing this with you whole class name ? – Suresh Atta Mar 07 '13 at 15:41
  • Whole class name meaning? – SexyBeast Mar 07 '13 at 15:42
  • You mean replacing *this* by `com.google.gwt.sample.stockwatcher.client.StockWatcher`? – SexyBeast Mar 07 '13 at 15:42
  • @ThomasBroyer :) just going to paste that link.Cheers – Suresh Atta Mar 07 '13 at 15:43
  • No,first follow the link given by Sir Thomas. – Suresh Atta Mar 07 '13 at 15:43
  • Okay, trying that. Why do you call him Sir? – SexyBeast Mar 07 '13 at 15:45
  • :) :) Learnt/Learning things from him(I mean from his solutions(SO) and articles on google groups) :) – Suresh Atta Mar 07 '13 at 15:53
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/25783/discussion-between-the-suresh-atta-and-cupidvogel) – Suresh Atta Mar 07 '13 at 15:54
  • @ThomasBroyer Well, it works. I followed your suggestion on the answer you suggested, and added `var that = this` and used `that.@...`. Also, I changed the jQuery alias to `$$`. You should give an answer so that I can accept it for others' convenience..:) – SexyBeast Mar 07 '13 at 16:38
  • I initially wanted to mark it as a duplicate of the other question, but the other guy is struggling to make it work, and SO wants the other question to have an accepted answer. Added an answer here then; with some additional research on jQuery (I don't know a bit about jQuery, this is all from the docs) – Thomas Broyer Mar 07 '13 at 16:56

1 Answers1

2

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() {
    this.@com.google.gwt.sample.stockwatcher.client.StockWatcher::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() { that.@com.google.gwt.sample.stockwatcher.client.StockWatcher::doit()(); }),
…
Thomas Broyer
  • 64,353
  • 7
  • 91
  • 164
  • Well, so much awesomeness in one answer! – SexyBeast Mar 07 '13 at 16:59
  • Oh, BTW, you can make `closeFn` event simpler, given you're only calling your method: `var closeFn = $.proxy($entry(this.@com.google.gwt.sample.stockwatcher.client.StockWatcher::doit()), this);` – Thomas Broyer Mar 08 '13 at 09:30