3.5.17.2. Generic JavaScriptComponent
JavaScriptComponent
is a simple UI component that can work with any JavaScript wrapper without Vaadin component implementation. Thus, you can easily integrate any pure JavaScript component in your CUBA-based application.
The component can be defined declaratively in an XML descriptor of the screen, so that you can configure dynamic properties and JavaScript dependencies in XML.
XML-name of the component: jsComponent
.
- Defining dependencies
-
You can define a list of dependencies (JavaScript, CSS) for the component. A dependency can be obtained from the following sources:
-
WebJar resource - starts with
webjar://
-
File placed within VAADIN directory - starts with
vaadin://
-
Web resource - starts with
http://
orhttps://
If the type of dependency cannot be inferred from the extension, specify the type explicitly in the
type
XML attribute or by passingDependencyType
enum value to theaddDependency()
method.Example of defining dependencies in XML:
<jsComponent ...> <dependencies> <dependency path="webjar://leaflet.js"/> <dependency path="http://code.jquery.com/jquery-3.4.1.min.js"/> <dependency path="http://api.map.baidu.com/getscript?v=2.0" type="JAVASCRIPT"/> </dependencies> </jsComponent>
Example of adding dependencies programmatically:
jsComponent.addDependencies( "webjar://leaflet.js", "http://code.jquery.com/jquery-3.4.1.min.js" ); jsComponent.addDependency( "http://api.map.baidu.com/getscript?v=2.0", DependencyType.JAVASCRIPT );
-
- Defining initialization function
-
The component requires an initialization function. This function’s name that will be used to find an entry point for the JavaScript component connector (see below).
The initialization function name must be unique within a window.
The function name can be passed to the component using the
setInitFunctionName()
method:jsComponent.setInitFunctionName("com_company_demo_web_screens_Sandbox");
- Defining JavaScript connector
-
To use
JavaScriptComponent
wrapper for a library, you should define a JavaScript connector - a function that initializes the JavaScript component and handles communication between the server-side and the JavaScript code.The following methods are available from the connector function:
-
this.getElement()
returns the HTML DOM element of the component. -
this.getState()
returns a shared state object with the current state as synchronized from the server-side.
-
- Component features
-
The
JavaScriptComponent
component has the following features that let you:-
Set a state object that can be used in the client-side JavaScript connector and is accessible from the
data
field of the component’s state, for example:MyState state = new MyState(); state.minValue = 0; state.maxValue = 100; jsComponent.setState(state);
-
Register a function that can be called from the JavaScript using the provided name, for example:
jsComponent.addFunction("valueChanged", callbackEvent -> { JsonArray arguments = callbackEvent.getArguments(); notifications.create() .withCaption(StringUtils.join(arguments, ", ")) .show(); });
this.valueChanged(values);
-
Invoke a named function that the connector JavaScript has added to the JavaScript connector wrapper object.
jsComponent.callFunction("showNotification ");
this.showNotification = function () { alert("TEST"); };
-
- JavaScriptComponent usage example
-
This section describes how to integrate a third-party JavaScript library to a CUBA-based application taking Quill Rich Text Editor from https://quilljs.com/ as an example. To use Quill in your project, you should follow the steps below.
-
Add the following dependency to the web module:
compile('org.webjars.npm:quill:1.3.6')
-
Create a
quill-connector.js
file in theweb/VAADIN/quill
directory on the web module. -
In this file, add the connector implementation:
com_company_demo_web_screens_Sandbox = function () { var connector = this; var element = connector.getElement(); element.innerHTML = "<div id=\"editor\">" + "<p>Hello World!</p>" + "<p>Some initial <strong>bold</strong> text</p>" + "<p><br></p>" + "</div>"; connector.onStateChange = function () { var state = connector.getState(); var data = state.data; var quill = new Quill('#editor', data.options); // Subscribe on textChange event quill.on('text-change', function (delta, oldDelta, source) { if (source === 'user') { connector.valueChanged(quill.getText(), quill.getContents()); } }); } };
-
Create a screen with the following
jsComponent
definition:<jsComponent id="quill" initFunctionName="com_company_demo_web_screens_Sandbox" height="200px" width="400"> <dependencies> <dependency path="webjar://quill:dist/quill.js"/> <dependency path="webjar://quill:dist/quill.snow.css"/> <dependency path="vaadin://quill/quill-connector.js"/> </dependencies> </jsComponent>
-
Add the following screen controller implementation:
@UiController("demo_Sandbox") @UiDescriptor("sandbox.xml") public class Sandbox extends Screen { @Inject private JavaScriptComponent quill; @Inject private Notifications notifications; @Subscribe protected void onInit(InitEvent event) { QuillState state = new QuillState(); state.options = ParamsMap.of("theme", "snow", "placeholder", "Compose an epic..."); quill.setState(state); quill.addFunction("valueChanged", javaScriptCallbackEvent -> { String value = javaScriptCallbackEvent.getArguments().getString(0); notifications.create() .withCaption(value) .withPosition(Notifications.Position.BOTTOM_RIGHT) .show(); }); } class QuillState { public Map<String, Object> options; } }
As a result, the Quill Rich Text Editor is available on the screen:
Another example of custom JavaScript component integration see at Using a JavaScript library.
-