https://vaadin.com/docs/framework/advanced/advanced-javascript.html
https://vaadin.com/docs/framework/gwt/gwt-javascript.html
https://vaadin.com/blog/vaadin-7-loves-javascript-components
NO widget compilation required, woo-hoo!
If @JavaScript annotation is present on a ClientConnector class, the framework ensures the referenced JavaScript files are loaded before the init method for the corresponding client-side connector is invoked. Yes, UI is one of ClientConnector.
In sample code below, since the javascript file is given a relative path, it needs to be deployed in the same Java package as the Java class (maybe put them side-by-side)
@JavaScript({"mylibrary.js", "mycomponent-connector.js"})
It's a component where client-side is written in Javascript (not Java/GWT) wrapped in an element usually <DIV>
Server side: extends AbstractJavaScriptComponent
Shared: extends JavaScriptComponentState
Client side: the .js
- function name: org_package_name_ComponentClassName = function() {...}, inside of which:
- Vaadin will add some functions to "this", see JavaDoc of AbstractJavaScriptComponent (see here)
- getConnectorId() - a string with the ID
- getParentId([connectorId]) - get string with id of connector's parent, or the provided connetor's parent
- getElement([connectorId]) - DOM element
- getState() - the shared state object
- registerRpc([name,] rpcObject) - register the rpcObject as RPC handler, it should contain functions for all eligible RPC functions. (that means call from server)
- if (interface) name provided: will only used for the RPC interface with the same fully qualified Java name
- If not, for all incoming RPC calls where the method name is defined as a function in the handler (so long it can be called, it's called)(if multiple registered RPC has that function exception will be thrown)
- getRpcProxy([name]) - return RPC proxy object. If no name provided, will return all registered.
- translateVaadinUri(uri) -...
- addResizeListener(element, callbackFunction) - callback function receives one parameter- event with element property pointing to the resized element
- removeResizeListener(element, callbackFunction)
- onStateChange = function() {
- onUnregister - when connector has been unregistered
- any field name <-> addFunction(String, JavaScriptFunction) on server, a function triggers the registered function on server (FROM SERVER)
- any field name <-> callFunction(String, Object...) on server, called (FROM SERVER)
AbstractJavaScriptExtension
Extension, all client-side logic implemented with JavaScript
Initialization function org_package_name_ComponentClassName = function() {...}, will get "this" pointing to a connector wrapper object but "this" not necessarily defined inside calllback functions and may necessary to save it (var self = this;)
"this" object (different than the "this" above)
- getElement([connectorId]) - null is returned if the connector cannot be found or does not have a widget
AbstractJavaScriptRenderer
How : Register to Execute!!
// Execute JavaScript in the currently processed page
Page.getCurrent().getJavaScript().execute("alert('Hello')");
// Shorthand
JavaScript.getCurrent().execute("alert('Hello')");
When:
- executed after server request returns
- if multiple calls are made, they are executed sequentially after request is done
- which means the Javascript
- does not pause execution of server-side application (it's actually register to execute)
- cannot return value
JavaScript.getCurrent().addFunction("com.example.foo.myfunc",
new JavaScriptFunction() {
@Override
public void call(JsonArray arguments) {
Notification.show("Received call");
}
});
Link link = new Link("Send Message", new ExternalResource(
"javascript:com.example.foo.myfunc()"));
Callback requires
- registration with addFunction()
- name + optionally package
- Implementation
- Parameter - receive as JsonArray
- The callback mechanism is the same as the RPC mechanism with component integration