Embed ZK Component in Foreign Framework"

From Documentation
Line 119: Line 119:
 
....
 
....
 
}
 
}
 +
</syntax>
 +
Once defined this custom JSF component can be used like any other JSF component for eg.
 +
<syntax lang="xml">
 +
<html xmlns="http://www.w3.org/1999/xhtml"
 +
xmlns:h="http://java.sun.com/jsf/html"
 +
xmlns:zk="http://www.zkoss.org/customjsf">
 +
<h:head>
 +
<title>ZK Components as native JSF Components</title>
 +
</h:head>
 +
<h:body>
 +
<h:form>
 +
<div>ZK Spreadsheet as a JSF Component Demo</div>
 +
<h:outputText value="Row"></h:outputText>
 +
<zk:window id="mywindow" border="normal" width="500px" height="250px"
 +
title="ZK Window" binding="${hello.helloWindow}" apply="${hello}">
 +
</zk:window>
 +
<br> </br>
 +
</h:form>
 +
</h:body>
 +
</html>
 
</syntax>
 
</syntax>
  

Revision as of 05:45, 16 September 2010


Embed ZK Component in Foreign Framework


Employment/Purpose

Here describes how to embed ZK component(s) as a native element of a foreign framework. For example, how to embed ZK components as a native JSF component. It allows application developers to use the native element without knowing the existence of ZK.

For sake of description, we call it the embedded component.


Note: if it is OK for your developers to work on ZUL directly. it is more convenient and powerful to use the inclusion (such as <jsp:include>) or ZK JSP Tags, and you don't have to wrap them into a native element.

Embed a component directly

The simplest way to embed is to invoke Renders.render(ServletContext, HttpServletRequest, HttpServletResponse, Component, String, Writer) when it is time to output the content of the native element.

For example, if you are implementing a JSP tag, then you can invoke the render method in doTag() as follows.

<syntax lang="java"> public void doTag() throws JspException, IOException {

   //prepare variables
   final JspContext jspctx = getJspContext();
   final PageContext pgctx = Jsps.getPageContext(jspctx);
   final ServletContext svlctx = pgctx.getServletContext();
   final HttpServletRequest request = (HttpServletRequest)pgctx.getRequest();
   final HttpServletResponse response = (HttpServletResponse)pgctx.getResponse();
   //create components
   Listbox listbox = new Listbox();
   listbox.appendChild(new Listitem("Item 1"));
   listbox.appendChild(new Listitem("Item 2"));
   //render the result
   final StringWriter out = new StringWriter();
   Renders.render(svlctx, request, response, listbox, null, out);
   getJspBody().invoke(out);

} </syntax>

Embed by implementing a richlet

If you want to have more control, such as applying a composer provided by users or creating components from a ZUL page, you could implement a richlet (Richlet) and then invoke Renders.render(ServletContext, HttpServletRequest, HttpServletResponse, Richlet, String, Writer) instead.

<syntax lang="java"> Renders.render(svlctx, request, response,

 new GenericRichlet() {
   public void service(Page page) throws Exception {
       //execution is ready
       //... do whatever you want
       Window main = new Window();
       main.setPage(page); //associate to the page
       Executions.createComponents("/WEB-INF/template/foo.zul", main, null);
       composer.doAfterCompose(main); //assume user assigned a composer
   }
 }, null, out);

</syntax>

where we use GenericRichlet to simplify the implementation of a richlet.

Example

Embed as a native JSF component

ZK Component as a native JSF component can be easily achieved by wrapping it as a custom JSF component and rendering it in Render Response Phase of JSF lifecycle by invoking Renders.render(ServletContext, HttpServletRequest, HttpServletResponse, Richlet, String, Writer)

<syntax lang="java"> @FacesComponent(value = "window") public class WindowTag extends UIComponentBase { private static final Log log = Log.lookup(WindowTag.class); private Window window;

public void encodeBegin(FacesContext context) throws IOException { ServletContext svlctx = (ServletContext)context.getExternalContext().getContext(); HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest(); HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse(); ResponseWriter responseWriter = context.getResponseWriter();

try { Renders.render(svlctx, request,response, new GenericRichlet() { public void service(Page page) throws Exception { window = new Window(); window.setPage(page); applyProperties(); doAfterCompose(); } }, null, responseWriter); } catch (ServletException e) { log.debug(e.getMessage()); throw new IOException(e.getMessage()); } }

/** apply ZK component properties as retrieved from JSF custom component tag */ private void applyProperties() { Map<String, Object> attrs = getAttributes(); Set<String> attrNames = attrs.keySet();

for (Iterator iterator = attrNames.iterator(); iterator.hasNext();) { String attrName = (String) iterator.next(); if(!"apply".equals(attrName)) { try { Property.assign(window, attrName, attrs.get(attrName).toString()); } catch(PropertyNotFoundException pnfe) { log.debug(pnfe.getMessage()); } } } } /** apply composer by calling doAfterCompose after ZK component is composed */ private void doAfterCompose() throws Exception { Object o = getAttributes().get("apply"); if(o instanceof String) { o = Classes.newInstanceByThread(o.toString()); } if(o instanceof Composer) { ((Composer)o).doAfterCompose(window); } }

.... } </syntax> Once defined this custom JSF component can be used like any other JSF component for eg. <syntax lang="xml"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:zk="http://www.zkoss.org/customjsf"> <h:head> <title>ZK Components as native JSF Components</title> </h:head> <h:body> <h:form>

ZK Spreadsheet as a JSF Component Demo

<h:outputText value="Row"></h:outputText> <zk:window id="mywindow" border="normal" width="500px" height="250px" title="ZK Window" binding="${hello.helloWindow}" apply="${hello}"> </zk:window>

</h:form> </h:body> </html> </syntax>

Environment setup for using an embedded component

To use an embedded component, ZK Update Engine (DHtmlUpdateServlet) is required, while ZK Loader (DHtmlLayoutServlet) is not (though it is safe to install it too. If ZK Loader is not installed, it assumes the udpate URI is /zkau, which can be overriden by setting a library property called org.zkoss.zkplus.embed.updateURI.

<syntax lang="xml"> <servlet> <servlet-name>auEngine</servlet-name> <servlet-class>org.zkoss.zk.au.http.DHtmlUpdateServlet</servlet-class> </servlet>

<servlet-mapping> <servlet-name>auEngine</servlet-name> <url-pattern>/zkau/*</url-pattern> </servlet-mapping> </syntax>

Version History

Version Date Content
5.0.5 September 2010 Renders was introduced to simplify the making of a native element for a foreign framework.



Last Update : 2010/09/16

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