Vaadin 7 alpha3 - JavaScript

Vaadin 7 alpha3 brings major new ways of using JavaScript together with Vaadin.


Loading external JavaScript files

We have added a @JavaScript annotation that can be added to any Component or Extension class to tell the resource that certain JavaScript files should be included on the page before the corresponding client-side code is initialized. Using this annotation, you can either define files to be loaded from an absolute URL or directly from the classpath, e.g. directly from an add-on’s JAR file. The framework takes care of loading the JavaScript file and ensuring it has been evaluated before the client-side Connector is initialized. No need for polling for tags or modifying the generated bootstrap page for this.


By the way, there’s also a @StyleSheet annotation which works in the same way but includes CSS style sheets.


Calling server-side code from JavaScript

Calling JavaScript code from the server has been possible using the executeJavascript() method. We have now also added support for defining server-side callbacks that can be triggered through JavaScript, i.e. you can publish JavaScript methods which call your server side methods. This can be used e.g. to integrate a Vaadin application with existing JavaScript functionality on the host page. The new functionality can be found in the new JavaScript class which now also takes care of the previous executeJavascript functionality.


JavaScript Components and Extensions

The biggest new feature related to JavaScript is that you can now implement all the client-side logic for a Component or Extension with only JavaScript and no GWT code at all. This is mainly intended for integrating existing JavaScript libraries so that you can write the connector logic for tying the library API to Vaadin’s server-side code. We have redesigned the way shared state and RPC data are encoded to enable passing logically structured JSON objects directly to JavaScript code without any client-side conversion going on in GWT. This also means that there’s no need to recompile your Widgetset after making changes to shared state classes or RPC interfaces as long as they are only used by JavaScript connectors.


Compatible with GWT connectors

The JavaScript features are so deeply integrated into the Vaadin core that you’d only need to change three lines of code in an existing server-side component to make it use a JavaScript connector instead of a GWT connector. Besides this compatibility with GWT connectors, you can also use a simplified RPC mechanism that has been designed especially for JavaScript. The simplified RPC lets you fully utilize the dynamic features of JavaScript while still providing a nice statically typed server-side Java API.


For short examples on how to use the new features, check out the Vaadin 7 mini tutorials: https://vaadin.com/wiki/-/wiki/Main/Vaadin+7
For information on how to migrate from Vaadin 6 to Vaadin 7, see http://dev.vaadin.com/wiki/Vaadin7/MigrationGuide

This is an alpha release so we expect there to be bugs and still expect changes will be made to the API and functionality before the final 7.0.0 release. All your comments on the new features are welcome. Please post all Vaadin 7 related comments in the Vaadin 7 category of the forum.

Hallo Artur,

I started a new vaadin 7 project and have some questions about integrating javascript into an UI Component.
I want to display the current time and date in the browser. I want to use a javascript function to update the current time every second.

Label date = new Label("<div style=\"text-align: left;\"><span id=\"theDate\">00.00.0000</span></div>", ContentMode.HTML);
        Label time = new Label("<div style=\"text-align: left;\"><span id=\"theTime\">00.00.0000</span></div>", ContentMode.HTML);

        StringBuilder script = new StringBuilder();

        script.append("function setTime(){");
        script.append("var c = new Date();");
        script.append("var date = fm(c.getDate()) + \".\" + fm(c.getMonth()+1) + \".\" + (c.getYear() + 1900);");
        script.append("var time = c.getHours() + ':' + fm(c.getMinutes()) + ':' + fm(c.getSeconds());");
        script.append("document.getElementById('theDate').innerHTML= date;");
        script.append("document.getElementById('theTime').innerHTML= time;");
        script.append("}");
        script.append("function fm(num) { if (num < 10) { return '0' + num; } return num; }");
        script.append("setInterval(\"setTime()\", 1000);");

        JavaScript.getCurrent().execute(script.toString());
       

When i use setInterval to call my function every second firebug show me an error with message:

ReferenceError: setTime is not defined
(230 out of range 45)
ucrs-c…min-war (Zeile 230)

When i directly call my setTime function it works fine (without updating the time every second)!

Do you have any ideas to solve my problem?

Greetz,
Michel

Your problem is caused because setInterval is evaling “setTime()” in the global scope whereas the function is only defined in the local scope where the script is evaluated.

The best workaround to this is to pass the function directly to setInterval instead of passing a string that is evaluated by the javascript engine. This is done by changing your last row to pass the setTime function instead of a string containing the name of the function.

script.append("setInterval(setTime, 1000);");

Thanks for the workaround. This work’s!

Hi,

Is it possible to include javascript file as follows:

@JavaScript(“…/analytics_connector.js”)

providing relative path for the javascript file in the annotation is required in my project as i want to keep java files and javascript files in different folders.

Related vaadin forum post :
https://vaadin.com/forum#!/thread/4924537

Regards,
Kunal Patil

Why does the @javascript load before the CSS file? It would be better for performance if it loaded after. Is there a workaround?

Also, is there an option to load the @javascript just above the closing body tag?

Thanks!