Triggering a JavaScript widget server callback from Vaadin.

Hello,

Given a JavaScript widget with connector like this:

my_js_GridWidget = function() {
  
    var grid = Ext.create(..);
}

… I would like to get the grid data back after user presses “Get Data Back” button on Vaadin screen.

One thing I could think of was to add a function, which triggers the call back. I am sorry for I am not a JavaScript programmer, but I think that if I place onSaveButtonClick() function outside of the connector the grid will not be “visible.”

my_js_GridWidget = function() {
  
    var grid = Ext.create(..);

    function onSaveButtonClick() { // can this be called from Vaadin?
        callVaadinBack(grid.getData()); // server-side callback
    }
}

Then I added a button handler to call the “onSaveButtonClick” function (below), but, it was not called because, I guess, it is inside the connector function. And, as I mentioned, if I put it outside then I can’t access the grid.

 final Button button = new Button("Get Data Back");
 button.addClickListener(new Button.ClickListener()
 {
     public void buttonClick(Button.ClickEvent event) {
         Page.getCurrent().getJavaScript().execute("onSaveButtonClick()");
  // "my_js_GridWidget.onSaveButtonClick()" does not work either
     }
});

Is there any way to call the JS function, which is inside the connector?

Or maybe there a better solution to this problem altogether…

Please advise. Thanks!

For calling the server from JS, see the JavaScript related tutorials
here
.

For calling JS methods from GWT Java code, exposing Java methods to be called from JS etc, JSNI is what you need - see e.g.
this page
.

If you are not familiar with which parts of Vaadin and components are on the client side and what is on the server side, consult
Book of Vaadin
.

Apologies if my question was not clear. I understand component-state-connector concept for creating JS components as per 16.12 in Book of Vaadin.

What I am querying about is scope of JavaScript functions in relation to Vaadin.

Let’s say I added a callback function foo():

JavaScript.getCurrent().addFunction("foo", new JavaScriptFunction()...

It seems to have “global” scope whereas function “bar” from the code below, if I am not mistaken, becomes a connector method.

public class JsGridComponent extends AbstractJavaScriptComponent
{
  public JsGridComponent() {
    addFunction("bar", new JavaScriptFunction()...

And so I am wondering how can I call a connector method from Vaadin. Because when the call

Page.getCurrent().getJavaScript().execute("bez()"). 

…works fine for a function defined “outside” of connector.

my_js_GridWidget = function() {
  
    var grid = Ext.create(..);
}

function bez() {
}

but if I define bez() inside the connector (because I want to access some data defined INSIDE the connector), how can I call it from Vaadin? THIS is what my question was about.

my_js_GridWidget = function() {
   
    function bez() {
        blah(grid.getData());
    }  
   
    var grid = Ext.create(..);
}

Thanks.

The “bez” function in your example is local to the constructor function you defined; it’s not accessible from the outside even in plain JavaScript. Instead, you should add the function as a field to the implicit this object:


my_js_GridWidget = function() {
   
    this.bez = function () {
        blah(grid.getData());
    }  
   
    var grid = Ext.create(..);
}

Or, to avoid each instance having their own copy of the function, add it to the prototype object and expose the grid variable as a field as well (note that in the above example,
grid
is a local variable but is included in the closure of
bez
):


my_js_GridWidget = function() {
    this.grid = Ext.create(..);
}

my_js_GridWidget.prototype.bez = function () {
    blah(this.grid.getData());
}  

Now, in your server-side JavaScriptComponent, you can invoke the bez function by simply calling
callFunction(“bez”)
. Note that you can’t (easily) do it via
JavaScript.execute()
because you’d need an instance on which to call it first (in the JavaScript object model,
my_js_GridWidget
is equivalent to a class in Java, and the
bez
function is like an instance method).

To learn more about the prototype-based object model of JavaScript, please refer to, for instance,
this MDN article
.

Thanks! This is exactly what I wanted to know.