]> source.dussan.org Git - vaadin-framework.git/commitdiff
Migrate ExposingServerSideAPIToJavaScript pr9959/r23
authorErik Lumme <erik@vaadin.com>
Tue, 12 Sep 2017 08:52:14 +0000 (11:52 +0300)
committerErik Lumme <erik@vaadin.com>
Tue, 12 Sep 2017 08:52:14 +0000 (11:52 +0300)
documentation/articles/ExposingServerSideAPIToJavaScript.asciidoc [new file with mode: 0644]
documentation/articles/contents.asciidoc

diff --git a/documentation/articles/ExposingServerSideAPIToJavaScript.asciidoc b/documentation/articles/ExposingServerSideAPIToJavaScript.asciidoc
new file mode 100644 (file)
index 0000000..2f41d45
--- /dev/null
@@ -0,0 +1,134 @@
+[[exposing-server-side-api-to-javascript]]
+Exposing server-side API to JavaScript
+--------------------------------------
+
+The new JavaScript integration functionality will allow you to easily
+publish methods that can be called with JavaScript on the client side.
+In effect, you can publish a JavaScript API for your application.
+Although you will probably not find yourself using this very often, it
+can be useful when integrating with JavaScript frameworks or embedding
+within legacy sites.
+
+Exposing a `notify()` method that takes a message and displays that as a
+notification can be done in one simple block in e.g `UI.init()`:
+
+[source,java]
+....
+JavaScript.getCurrent().addFunction("notify", new JavaScriptFunction() {
+  public void call(JSONArray arguments) throws JSONException {
+    Notification.show(arguments.getString(0));
+  }
+});
+....
+
+This will expose the `notify()`{empty}-method globally in the window object.
+Technically it's thus `window.notify()`, but you can call it by simply
+by `notify()`. Try entering `notify("Hey!")` into the Firebug or
+Developler Tools console, or `javascript:notify("Hey!")` into the
+address bar.
+
+You'll notice that this assumes there is a String in the first position
+of the array. Also, this will clutter the global namespace, which is
+generally not a good idea, unless you really have a specific need for
+that.
+
+Let's make a complete example with two arguments, some simple error
+handling, and namespacing:
+
+[source,java]
+....
+JavaScript.getCurrent().addFunction("com.example.api.notify",
+  new JavaScriptFunction() {
+    public void call(JSONArray arguments) throws JSONException {
+      try {
+        String caption = arguments.getString(0);
+        if (arguments.length() == 1) {
+            // only caption
+            Notification.show(caption);
+        } else {
+            // type should be in [1]
+            Notification.show(caption,
+                Type.values()[arguments.getInt(1)]);
+        }
+      } catch (JSONException e) {
+        // We'll log in the console, you might not want to
+        JavaScript.getCurrent().execute(
+            "console.error('" + e.getMessage() + "')");
+      }
+    }
+  });
+}
+....
+
+Using the dotted notation for the method will automatically create those
+objects in the browser; you'll call this method like so:
+`com.example.api.notify("Hey!")`. You do not have to use a long name
+like this, though - it's up to you and your use-case.
+
+The second thing to notice is that we now wrapped the code in a
+try-catch, so that the wrong number or wrong types of arguments does not
+cause an ugly stacktrace in our server logs. Again, how you should react
+to erroneous use of your exposed API depends on your use-case. We'll log
+an error message to the browser console as an example.
+
+We're now accepting a second (integer) argument, and using that as
+_type_ for the `Notification`.
+
+Finally, we'll add a link that will call the function, and work as a
+_Bookmarklet_. You can drag the link to your bookmarks bar, and when you
+invoke it when viewing the application with our exposed `notify()`{empty}-method, you will be prompted for a message that will then be sent to
+the method. Here is the plain HTML code for creating such a link:
+
+[source,html]
+....
+<a href="javascript:(function(){com.example.api.notify(prompt('Message'),2);})();">Send message</a>
+....
+
+Here is the full source for our application:
+
+[source,java]
+....
+import org.json.JSONArray;
+import org.json.JSONException;
+import com.vaadin.server.ExternalResource;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.JavaScript;
+import com.vaadin.ui.JavaScriptFunction;
+import com.vaadin.ui.Link;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.Notification.Type;
+import com.vaadin.ui.UI;
+
+public class JSAPIUI extends UI {
+  @Override
+  public void init(VaadinRequest request) {
+
+    JavaScript.getCurrent().addFunction("com.example.api.notify",
+        new JavaScriptFunction() {
+          public void call(JSONArray arguments) throws JSONException {
+            try {
+              String caption = arguments.getString(0);
+              if (arguments.length() == 1) {
+                // only caption
+                Notification.show(caption);
+              } else {
+                // type should be in [1]
+                Notification.show(caption,
+                    Type.values()[arguments.getInt(1)]);
+              }
+            } catch (JSONException e) {
+              // We'll log in the console, you might not want to
+              JavaScript.getCurrent().execute(
+                  "console.error('" + e.getMessage() + "')");
+            }
+          }
+        });
+
+
+    setContent(new Link(
+        "Send message",
+        new ExternalResource(
+            "javascript:(function(){com.example.api.notify(prompt('Message'),2);})();")));
+  }
+}
+....
index 8360662dff1ef46f2b7b09cb09eefd605788b0a4..504cdcd33a9fc0b86345a2f46458eacf0a2d2247 100644 (file)
@@ -47,4 +47,5 @@ are great, too.
 - link:IntegratingAJavaScriptComponent.asciidoc[Integrating a JavaScript component]
 - link:IntegratingAJavaScriptLibraryAsAnExtension.asciidoc[Integrating a JavaScript library as an extension]
 - link:UsingAJavaScriptLibraryOrAStyleSheetInAnAddOn.asciidoc[Using a JavaScript library or a style sheet in an add-on]
+- link:ExposingServerSideAPIToJavaScript.asciidoc[Exposing server-side API to JavaScript]
 - link:CreatingAUIExtension.asciidoc[Creating a UI extension]