Work with HTML Tags

From Documentation
Revision as of 07:32, 19 July 2010 by Char (talk | contribs)

Stop.png This documentation is for an older version of ZK. For the latest one, please click here.


There are several ways to use HTML tags with XUL components in the same ZUML page. You can chose any of them based on your requirement.

First, you can use the html component to embed HTML tags. With this approach, the HTML tags are simply the content of the html component. They are sent to the client directly. They don't have any specify meaning to ZK.

Second, you can use the XHTML namespace (http://www.w3.org/1999/xhtml) to specify a component from the XHTML component set. In other words, the XHTML namespace denotes the associate XML element is a component from the XHTML component set. Like the ZUL component set (http://www.zkoss.org/2005/zul), ZK creates an instance for each XML element in a ZUML page.

Third, you can use the Native namespace (http://www.zkoss.org/2005/zk/native) to represent a HTML tag that shall be sent directly to the client instead of creating a ZK component for each of them. When It is more efficient, but not dynamically changeable.

Last but not least, you can use inclusion (include) and inline frames (iframe) to embed another into a ZUL page with, theoretically, any kind of content (not limited to HTML tags

The html Component

The simplest way is to use a XUL component called html[1] to embed whatever HTML tags you want to send directly to the browser. To avoid ZK from interpreting the HTML tags, you usually enclose them with <![CDATA[ and ]]>. In other words, they are not the child component. Rather, they are stored in the content property[2]. Notice you can use EL expressions in it.

 <window border="normal" title="Html Demo">
     <html><![CDATA[
         <h4>Hi, ${parent.title}</h4>
         <p>It is the content of the html component.</p>
     ]]></html>
 </window>

where <h4>...</p> will become the content of the html element (see also the getContent method of the org.zkoss.zul.Html class).

Tip: You can use the attribute element to specify the XHTML fragment instead of CDATA as follows.

 <window border="normal" title="Html Demo">
     <html>
	<attribute name="content">
		<h4>Hi, ${parent.title}</h4>
		<p>It is the content of the html component.</p>
	</attribute>
     </html>
 </window>

Refer to the attribute Element section in the ZK User Interface Markup Language chapter..

The html component generates the HTML SPAN tag to enclose the content. In other words, it generates the following HTML tags when rendered to the browser.

 <span id="z_4a_3">
     <h4>Hi, Html Demo</h4>
     <p>It is the content of the html component.</p>
 </span>

The html component is no different to other XUL components. For example, you specify the CSS style and change its content dynamically.

<zk>
	<html id="h" style="border: 1px solid blue;background: yellow">
	<![CDATA[
	     <ul>
	         <li>Native browser content</li>
	     </ul>
	]]>
	</html>
	<button label="change" onClick="h.setContent(&quot;Hi, Update&quot;)" />
</zk>

Notice that, since SPAN is used to enclose the embedded HTML tags, the following code snippet is incorrect.

<zk>
	<html><![CDATA[
     		<ul>
         <li> <!-- incorrect since <ul><li> is inside <span> -->
		 ]]>
		</html>
		<textbox />
		<html><![CDATA[
		         </li>
		     </ul>
		 ]]>
	</html>
</zk>

If you need to generate the embedded HTML tags directly without the enclosing SPAN tag, you can use the Native namespace as described in the following section.

Notes

  1. The text within the html element is actually assigned to the html component's content property (rather than becoming a label child).
  2. Refer to the XML section in the ZK User Interface Markup Language chapter if you are not familiar with XML.

The Native Namespace, http://www.zkoss.org/2005/zk/native

With the Native namespace, a XML element in a ZUML page denotes that it shall be sent to the browser directly rather than becoming a ZK component. For example,

 <n:ul xmlns:n="http://www.zkoss.org/2005/zk/native">
     <n:li>
     <textbox/>
     </n:li>
     <n:li>
     <textbox/>
     </n:li>
 </n:ul>

will generate the following HTML tags to the browser:

 <ul>
     <li>
     <input id="z_a3_2"/>
     </li>
     <li>
     <input id="z_a3_5"/>
     </li>
 </ul

where <input> is the HTML tag(s) generated by the textbox component. Unlike textbox in the example above, ZK Loader doesn't really create a component for each of ul and li.[1] Rather, they are sent to the client directly. Of course, they must be recognizable by the client. For HTML browsers, they must be the valid HTML tags.

Since the elements associated with the Native namespace are sent directly to the client, they are not ZK components, and they don't have the counterpart at the client. The advantage is the better performance in term of both memory and processing time. On the other hand, the disadvantage is you cannot access or change them dynamically. For example, the following code snippet is incorrect, since there is no component called x.

 <n:ul id="x" xmlns:n="http://www.zkoss.org/2005/zk/native"/>
 <button label="add" onClick="new Li().setParent(x)"/>

If you want to change them dynamically, you can specify the XHTML namespace as described in the following section.

Notes

  1. ZK ZK actually creates a special component to represent as many XML elements with the Native namespace as possible.


Output Another Namespace with the Native Namespace

If you want to generate another namespace to the output, you can use another format as the URI of the Native namespace:

 native:''URI-of-another-namespace''

For example, if you want to output the XAML tags directly to the client, you can specify native:http://schemas.microsoft.com/client/2007 as follows.

<zk>
	<Canvas xmlns="native:http://schemas.microsoft.com/client/2007">
	  <TextBlock>Hello World!</TextBlock>
	</Canvas>
</zk>

Then, the client will receive the following[1]:

<div z.au="/ZKTester/zkau" z.zidsp="page" style="width: 100%; height: 100%;" z.dtid="gk68" id="z_k6_0" class="zk">
     <canvas xmlns="http://schemas.microsoft.com/client/2007">
          <textblock>Hello World!</textblock>
     </canvas>
</div>

Notes

  1. The real HTML output of window depends on its implementation. Here is only a simplified version.

The XHTML Namespace

The XHTML namespace represents the XHTML component set, just like the ZUL namespace (http://www.zkoss.org/2005/zul) represents the ZUL component set. Thus, a XML element specified with the XHTML namespace simply denotes a component that shall be created based on the component definition from the XHTML component set. For example, the statement blow specifies a component that shall be created as an instance of the component definition called ul, and ul belongs to the XHTML component set:

 <h:ul xmlns:h="[http://www.w3.org/1999/xhtml http://www.w3.org/1999/xhtml]">

In other words, ZK loader will search the XHTML component set for the component definition called ul , and then create an instance based on it.

The following is another yet more complete example.

Html 1.png

 <window title="mix HTML demo" xmlns:h="http://www.w3.org/1999/xhtml">
     <h:table border="1">
         <h:tr id="row1">
             <h:td>column 1</h:td>
             <h:td>
                 <listbox id="list" mold="select">
                     <listitem label="AA"/>
                     <listitem label="BB"/>
                 </listbox>
             </h:td>
         </h:tr>
     </h:table>
     <button label="add" onClick="row1.appendChild(new org.zkoss.zhtml.Td())"/>
 </window>

Unlike the html components, where HTML tags are stored in the content property, ZK loader creates one component for each of them. The advantage is that you can manipulate each individual HTML tag dynamically, as depicted in the above example (the add button). The disadvantage is that they take longer to process and more space to maintain.

Tip: Unlike the XHTML namespace, the Native namespace doesn't represent another component set. It is a reserved namespace to tell ZK Loader to send them directly to the client for better performance.

The include Component

The include component is used to include the output generated by another servlet. The servlet could be anything including JSF, JSP and even another ZUML page.

 <window title="include demo" border="normal" width="300px">
     Hello, World!
     <include src="/userguide/misc/includedHello.zul"/>
     <include src="/html/frag.html"/>
 </window>

Like all other properties, you could dynamically change the src attribute to include the output from a different servlet at the run time.

If the included output is another ZUML, developers are allowed to access components in the included page as if they are part of the containing page.

Pass Values to the Included Page

There are two ways to pass values to the included page. First, you can pass them with the query string.

<include src="mypage?some=something"/>

Then, in the included page, you can access them with the getParameter method of the Execution interface or the ServletRequest interface. In EL expressions (of the included page), you can use the param variable to access them. However, you can only pass String-typed values with the query string.

${param.some}

Alternatively, we can pass any kind of values with the so-called dynamic properties by use of the setDynamicProperty method or, in ZUL, a dynamic property as follows:

 <include src="mypage" some="something" another="${expr}"/>

With the dynamic properties, you can pass non-String-typed values. In the included page, you can access them with the getAttribute method of the Execution interface or the ServletRequest interface. In EL expressions (of the included page), you can use the requestScope variable to access them.

 ${requestScope.some}

Including ZUML Pages

If the include component is used to include a ZUML page, the included page will become part of the desktop. However, the included page is not visible until the request is processed completely. In other words, it is visible only in the following events, triggered by user or timer.

The reason is that the include component includes a page as late as the Rendering phase[1]. On the other hand, zscript takes place at the Component Creation phase, and onCreate takes place at the Event Processing Phase. They both execute before the inclusion.

 <window onCreate="desktop.getPages()"> <!-- the included page not available -->
     <include src="/my.zul"/>
     <zscript>
         desktop.getPages(); //the included page not available yet
     </zscript>
     <button label="Hit" onClick="desktop.getPages()"/>
         <!-- Yes, the included page is available when onClick is received -->
 </window>

If you want to look into the component of an included page, macro components are usually a better option. Refer to the Macro Components section in the ZK User Interface Markup Language chapter.

Notes

  1. Refer to the Component Lifecycle chapter for more details.

The style Component

The style component is used to specify CSS styles in a ZUML page. The simplest format is as follows.

Html 2.png

 <style>
 .blue {
  color: white; background-color: blue;
 }
 </style>
 <button label="OK" sclass="blue"/>

Tip: To configure a style sheet for the whole application, specify theme-uri in zk.xml, refer to the Themes section in the Internationalization chapter, or Appendix B in the Developer's Reference for details. To configure a style sheet for a language, use the language addon, refer to the Component Development Guide.

Sometimes it is better to store all CSS definitions in an independent file, say my.css. Then, we could reference it by use of the style component as follows.

 <style src="/my.css"/>

The above statement actually sends the following HTML tags[1] to the browser, so the specified file must be accessible by the browser.

 <link rel="stylesheet" href="/css/mystyles.css"/>

In other words, you cannot specify "/WEB-INF/xx" or "[/../xx/yy C:/xx/yy]".

Like other URI, it accepts "*" for loading browser and Locale dependent style sheet. Refer to the Browser and Locale Dependent URI section in the Internationalization chapter for details.

Notes

  1. The real result depends on how your Web application is configured.

The script Component

The script component is used to specify the script codes running at the browser. Notice that, unlike zscript, the script codes are running at the browser. They are usually written in JavaScript which is supported by the most of browsers. The simplest format is as follows.

 <script type="text/javascript">
 function myfunc() {
     $e("${win.uuid}").style.backgroundColor = "blue";
 }
 </script>

As shown above, you can use EL expressions (${win.uuid}) in script codes.

Of course, you can reference to an external JavaScript file with the src property as follows.

 <script src="/js/super.js" type="text/javascript"/>

With ZK, developers rarely need to specify JavaScript codes to execute, since the ZK applications are running at the server (and execute in your favorite language). They are usually to customize the behavior of ZK Client Engine, or to run the legacy JavaScript libraries.

The iframe Component

The iframe component uses the HTML IFRAME tag to delegate a portion of the display to another URL. Though the appearance looks similar to the include component. The concept and meaning of the iframe component is different.

The content included by the include component is a fragment of the whole HTML page. Because the content is part of the HTML page, the content is part of the desktop and you could access any components, if any, inside of the include component. The inclusion is done at the server, and the browser knows nothing about it. It means the URL specified by the src property could be any internal resource.

The content of the iframe component is loaded by the browser as a separate page. Because it is loaded as a separate page, the format of the content could be different from HTML. For example, you could embed an PDF file.

 <iframe src="/my.pdf"/>
 ...other HTML content

Tip: By default, there is no border. To enable it, use the style attribute to specify it. For example,<iframe style="border:1px inset" src="http://www.zkoss.org"/>

The embedding is done by the browser, when it interprets the HTML page containing the IFRAME tag. It also implies that the URL must be a resource that you can access from the browser.

Like the image and audio components[1], you could specify the dynamically generated content. A typical example is you could use JasperReport[2] to generate a PDF report in a binary array or stream, and then pass the report to an iframe component by wrapping the result with the org.zkoss.util.media.AMedia class.

In the following example, we illustrate that you could embed any content by use of iframe, as long as the client supports its format.

 <window title="iframe demo" border="normal">
     <iframe id="iframe" width="95%"/>
     <separator bar="true"/>
     <button label="Upload">
         <attribute name="onClick">{
             Object media = Fileupload.get();
             if (media != null)
                 iframe.setContent(media);
         }</attribute>
     </button>
 </window>
Html 3.png This picture depicted the appearance after user uploaded an Microsoft PowerPoint file.

Notes

  1. In many ways, iframe is much similar to image and audio. You might consider it as a component for arbitrary content.
  2. http://jasperreports.sourceforge.net


The onURIChange Event

When the user navigates the iframe component to another URL (or bookmark), an object of the org.zkoss.zk.ui.event.URIEvent class is sent to the iframe component. This event is usually used to bookmark the status of the iframe component, such that the right content can be restored later.

Integrate with Other Technologies

The onURIChange event won't be sent if the iframe component contains a non-ZK page. For example, it won't be sent if it contains a PDF page.

On the other hand, if you use other technologies to put a ZK page in an iframe, you can monitor the URL by writing a JavaScript method called onIframeChange as follows.

 //Part of your, say, PHP page
 <script type="text/script">
 function onIframeChange(uuid, url) {
     do_whatever_you_need_in_the_technology_you_use(uuid, url);
 }
 </script>

where uuid is the ID of the element that you can retrieve by document.getElementById, and url is the new URL that the iframe is navigated to. Notice that url includes the context path, while URIEvent.getURI() does not.

Retrieving component inside an iframe

When using iframe, it's actually another browser, another desktop.

If you want to retrieve component inside an iframe, you may use <include> instead of <iframe>. Or you have to deliberately pass the information through session.[1]

Notes



Last Update : 2010/07/19

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