Embedded ZK Application"

From Documentation
m
 
(13 intermediate revisions by 3 users not shown)
Line 2: Line 2:
  
 
=Employment/Purpose=
 
=Employment/Purpose=
Instead of using iframe, there is a new way to use ZK in a non-ZK web container. For example, we could use NodeJs, Python, etc. as the web application, and embed another ZK application in the web pages.
+
Instead of using an iframe, ZK provides JavaScript API for a non-Java EE web container. Hence, you can embed a ZK application in a web application based on NodeJs, Python, etc.
 +
 
 
{{ZK EE}}
 
{{ZK EE}}
 
{{versionSince| 9.0.1 }}
 
{{versionSince| 9.0.1 }}
Line 9: Line 10:
 
==Settings in the ZK application==
 
==Settings in the ZK application==
 
We use library property to enable the embedded feature.
 
We use library property to enable the embedded feature.
For example: (In zk.xml)
+
For example: (In '''zk.xml''')
 
<source lang="xml">
 
<source lang="xml">
 
<library-property>
 
<library-property>
Line 17: Line 18:
 
</source>
 
</source>
  
=[https://github.com/zkoss-demo/zkembedded-demo Demo Example]=
+
= Demo Example=
 
In the  [https://github.com/zkoss-demo/zkembedded-demo Demo project], there are 2 web applications, one is a non-ZK web application (http://localhost:8080), and another one is a ZK application (http://zkembedded-app).
 
In the  [https://github.com/zkoss-demo/zkembedded-demo Demo project], there are 2 web applications, one is a non-ZK web application (http://localhost:8080), and another one is a ZK application (http://zkembedded-app).
  
Line 23: Line 24:
  
 
'''index.html'''
 
'''index.html'''
<syntaxhighlight line lang="html" high="11,13">
+
<syntaxhighlight line lang="html" highlight="11,13">
 
<!DOCTYPE html>
 
<!DOCTYPE html>
 
<html>
 
<html>
Line 83: Line 84:
 
Notice that the URL redirection should rewrite the locations:
 
Notice that the URL redirection should rewrite the locations:
  
<syntaxhighlight line lang="javascript">
+
<syntaxhighlight lang="javascript">
 
/embedded/embedded.js -> http://zkembedded-app/zkau/web/js/zkmax/embedded/embedded.js
 
/embedded/embedded.js -> http://zkembedded-app/zkau/web/js/zkmax/embedded/embedded.js
 
</syntaxhighlight>
 
</syntaxhighlight>
  
<syntaxhighlight line lang="javascript">
+
<syntaxhighlight lang="javascript">
 
/embedded -> http://zkembedded-app/embedded
 
/embedded -> http://zkembedded-app/embedded
 
</syntaxhighlight>
 
</syntaxhighlight>
Line 94: Line 95:
  
 
This will destroy the embedded ZK desktop at server side and clear the DOM Element. Use "skipError = true" to ignore error messages.
 
This will destroy the embedded ZK desktop at server side and clear the DOM Element. Use "skipError = true" to ignore error messages.
 +
 +
==Better way to include embedded.js in ZK 10==
 +
{{versionSince| 10.0.0 }}
 +
 +
Since ZK 10, we can set the zkEmbedded servlet in '''web.xml'''
 +
<syntaxhighlight lang="xml">
 +
<servlet>
 +
    <servlet-name>zkEmbedded</servlet-name>
 +
    <servlet-class>org.zkoss.zkmax.ui.http.EmbeddedServlet</servlet-class>
 +
</servlet>
 +
<servlet-mapping>
 +
    <servlet-name>zkEmbedded</servlet-name>
 +
    <url-pattern>/zkEmbedded</url-pattern>
 +
</servlet-mapping>
 +
</syntaxhighlight>
 +
Then we can include embedded.js in html in the following way
 +
<syntaxhighlight lang="xml">
 +
<script src="/${webappRoot}/zkEmbedded"></script>
 +
</syntaxhighlight>
  
 
=Control ZK Components when using embedded ZK=
 
=Control ZK Components when using embedded ZK=
After loading the ZK contents, we could use the ZK Client binding to control the ZK components in the view.
+
After loading the ZK contents, we could use the ZK Client command binding to control the ZK components on a page.
  
To see more information, please refer to [http://books.zkoss.org/zk-mvvm-book/8.0/data_binding/client_binding_api.html ZK MVVM Book - Client Binding].
+
To see more information, please refer to [http://books.zkoss.org/zk-mvvm-book/9.5/data_binding/client_binding_api.html ZK MVVM Book - Client command binding].
  
 
=Cross-Origin Resource Sharing=
 
=Cross-Origin Resource Sharing=
Line 113: Line 133:
 
This can be done by configuring your server (e.g. nginx, apache-httpd, tomcat, spring-boot...) appropriately and is '''not''' ZK-specific.  
 
This can be done by configuring your server (e.g. nginx, apache-httpd, tomcat, spring-boot...) appropriately and is '''not''' ZK-specific.  
 
Please refer to the related documentation (e.g. [https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS MDN: Cross-Origin Resource Sharing (CORS)]) and your specific server configuration guides.
 
Please refer to the related documentation (e.g. [https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS MDN: Cross-Origin Resource Sharing (CORS)]) and your specific server configuration guides.
 +
 +
=Limitations=
 +
==Cannot Embed Pages from Different ZK Versions==
 +
Since ZK loads JavaScript and CSS in the global namespace, so multiple versions of these assets will conflict with each other. Hence, you cannot embed a <code>page1.zul</code> from '''ZK 8''' application and a <code>page2.zul</code> from '''ZK 9''' application into one page.
 +
 +
==Cannot Embed Multiple Pages with WebSocket Enabled==
 +
{{versionSince| 10.0.0 }}
 +
 +
zEmbedded supports WebSocket under the condition that only one ZK page can be embedded into a non-ZK page when WebSocket is enabled.
  
 
=Version History=
 
=Version History=
{{LastUpdated}}
+
 
{| border='1px' | width="100%"
+
{| class='wikitable' | width="100%"
 
! Version !! Date !! Content
 
! Version !! Date !! Content
 
|-
 
|-
 
| 9.0.0
 
| 9.0.0
 
|  
 
|  
|  
+
|-
 +
| 10.0.0
 +
| Jan 15, 2024
 +
| zEmbedded supports WebSocket
 
|}
 
|}
  
 
{{ZKDevelopersReferencePageFooter}}
 
{{ZKDevelopersReferencePageFooter}}

Latest revision as of 06:18, 1 February 2024


Embedded ZK Application


Employment/Purpose

Instead of using an iframe, ZK provides JavaScript API for a non-Java EE web container. Hence, you can embed a ZK application in a web application based on NodeJs, Python, etc.

  • Available for ZK:
  • http://www.zkoss.org/product/zkhttp://www.zkoss.org/whyzk/zkeeVersion ee.png

Since 9.0.1

Prerequisite

Settings in the ZK application

We use library property to enable the embedded feature. For example: (In zk.xml)

<library-property>
	<name>org.zkoss.web.servlet.http.embedded.enabled</name>
	<value>true</value>
</library-property>

Demo Example

In the Demo project, there are 2 web applications, one is a non-ZK web application (http://localhost:8080), and another one is a ZK application (http://zkembedded-app).

We'll embed ZK into the non-ZK web application.

index.html

 1 <!DOCTYPE html>
 2 <html>
 3 	<head>
 4 		<meta charset="UTF-8">
 5 		<title>Title</title>
 6 	</head>
 7 	<body>
 8 		<div id="embeddedZK" style="height:80%">  
 9 			 Loading...
10 		</div>
11 		<script id="embeddedScript" src="http://zkembedded-app/zkau/web/js/zkmax/embedded/embedded.js" />
12 		<script>
13 			zEmbedded.load('embeddedZK', 'http://zkembedded-app/demo.zul');
14 		</script>
15 	</body>
16 </html>
  • line 11: load the zk embedded JS API script
  • line 13: load demo.zul (of the ZK application) into the DOM Element with id embeddedZK.

To see more information, please download the Demo project.

API in embedded.js

We provide two methods to embed ZK.

zEmbedded.load(domId, ZKSrc)

The "domId" means after loading resource from "ZKSrc", the content of "domId" (HTML DOM Element) would be replaced with the ZK content.

This function returns a Promise object, which means that we can call functions after ZK is ready.

1 zEmbedded.load('embeddedZK', 'http://zkembedded-app/demo.zul')
2   .then(function(result) {
3     zk.log('ZK is ready!' + result.widget.uuid); //result contains the first widget
4   }).catch(reason => {
5     alert('ZK mounting error: ' + reason);
6 });

The "then" method of the promise is invoked when the embedding has completed, and the embedded page has been loaded.

The "catch" method of the promise is invoked when the embedding process encounters a failure. The reason object contains the error message associated with the failure.

zEmbedded.load(domId, ZKSrc, ZKHost)

Since 9.6.0

To handle the URL redirection, we can specify the ZK Host URL.

1 <script id="embeddedScript" src="/embedded/embedded.js"></script>
2 <script>
3 	zEmbedded.load('embeddedZK', '/embedded/demo.zul', '/embedded');
4 </script>

Notice that the URL redirection should rewrite the locations:

/embedded/embedded.js -> http://zkembedded-app/zkau/web/js/zkmax/embedded/embedded.js
/embedded -> http://zkembedded-app/embedded

zEmbedded.destroy(domId, skipError)

This will destroy the embedded ZK desktop at server side and clear the DOM Element. Use "skipError = true" to ignore error messages.

Better way to include embedded.js in ZK 10

Since 10.0.0

Since ZK 10, we can set the zkEmbedded servlet in web.xml

<servlet>
    <servlet-name>zkEmbedded</servlet-name>
    <servlet-class>org.zkoss.zkmax.ui.http.EmbeddedServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>zkEmbedded</servlet-name>
    <url-pattern>/zkEmbedded</url-pattern>
</servlet-mapping>

Then we can include embedded.js in html in the following way

<script src="/${webappRoot}/zkEmbedded"></script>

Control ZK Components when using embedded ZK

After loading the ZK contents, we could use the ZK Client command binding to control the ZK components on a page.

To see more information, please refer to ZK MVVM Book - Client command binding.

Cross-Origin Resource Sharing

In Cross Origin scenarios the responses from the ZK application need to set at least the following CORS headers:

1 Access-Control-Allow-Origin: [allowed embedding origins]
2 Access-Control-Allow-Headers: zk-sid
3 Access-Control-Expose-Headers: zk-sid, zk-error
4 Access-Control-Allow-Credentials: true
5 Access-Control-Allow-Methods: GET, POST

This can be done by configuring your server (e.g. nginx, apache-httpd, tomcat, spring-boot...) appropriately and is not ZK-specific. Please refer to the related documentation (e.g. MDN: Cross-Origin Resource Sharing (CORS)) and your specific server configuration guides.

Limitations

Cannot Embed Pages from Different ZK Versions

Since ZK loads JavaScript and CSS in the global namespace, so multiple versions of these assets will conflict with each other. Hence, you cannot embed a page1.zul from ZK 8 application and a page2.zul from ZK 9 application into one page.

Cannot Embed Multiple Pages with WebSocket Enabled

Since 10.0.0

zEmbedded supports WebSocket under the condition that only one ZK page can be embedded into a non-ZK page when WebSocket is enabled.

Version History

Version Date Content
9.0.0
10.0.0 Jan 15, 2024 zEmbedded supports WebSocket



Last Update : 2024/02/01

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.