Rich Internet applications using ZK

An open source Ajax framework

ZK, an open source Asynchronous JavaScript + XML (Ajax) framework written in Java™ code, lets you write a Web 2.0-enabled, rich Internet application without writing a single line of JavaScript code. Typical Ajax frameworks like Dojo have JavaScript libraries that expose certain API's for making "Ajaxified" calls. ZK, on the other hand, uses a meta-definition based on XML to define the user interface. Translation to HTML code then occurs when this page is requested by the client. This article introduces you to ZK and gives you a real-world example of its use running on Apache Tomcat and connecting to a MySQL database.

Share:

Sachin K Mahajan (sachin.mahajan@in.ibm.com), Software Developer, IBM  

Sachin graduated with a Masters degree from the University of Utah, Salt Lake City, U.S. He has worked in both small and large companies in the United States and India performing various technical and managerial roles. Sachin currently works in IBM Software Group's Lotus division.



05 January 2010

Also available in Chinese Japanese Portuguese

Introduction

You can think of ZK as being analogous to Ajax without JavaScript. It is composed of an Ajax-based, event-driven engine, a rich set of XHTML and XUL components, and a mark-up language called ZUML, which is used for creating feature-rich user interfaces. The business logic can be written through Java code directly integrated into your application, and which is triggered based on events or components. The most powerful feature of ZK is its rich set of control libraries for user interface development. Sound interesting?

First, let me describe the previous terms in a little more detail:

  • XHTML: Extensible Hypertext markup language, or XHTML, is combined HTML and XML. XHTML adds the power and flexibility of HTML with the extensibility of XML. Listing 1 provides an example of XHTML code.
    Listing 1. XHTML example code
    <?xml version="1.0" encoding="iso-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 
    Transitional//EN" "DTD/xhtml1-transitional.dtd">
    <html xml:lang="en" lang="en" xmlns="http://www.w3.org/1999/xhtml">
     <head>
     <title>Hello ZK</title>
     </head>
     <body>
     <h1>Introducing XHTML</h1>
     </body>
     </html>
  • XUL: XML User Interface language, or XUL, (pronounced as "Zool") is a mark-up language developed by Mozilla, and is an XML application used to describe graphical user interfaces. XUL has the ability to create elements such as input controls, toolbars, menus, trees, keyboard shortcuts, and so on. Listing 2 shows an example of XUL code.
    Listing 2. XUL code sample
    <?xml version="1.0"?>
    <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
    <window id="main" title="My App" width="300" height="300"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
       <caption label="Hello World"/>
       </window>
  • ZUML: ZK User Interface Markup Language, or ZUML, is used for defining the rich user interface. Because it's based on XML, each element describes the component, and the attribute describes the component value. Listing 3 gives an example of ZUML code.
    Listing 3. ZUML code sample
    <window title="Hello ZUML" border="normal">
       Hello World!
       </window>

Getting ZK

Obtaining and installing ZK is quite easy. The documentation on the libraries and setting up the folder structure has been defined very nicely on the ZK documentation site. (See Resources for a link.) So, getting ZK, including running the hello world application, should be simple.

Why ZK?

ZK is a direct Ajax implementation—or in other words, a server-centric model. This is unlike other frameworks that expose you to the painful details of making Ajax calls. Additionally, Ajax calls require extensive use and knowledge of JavaScript for manipulating the Document Object Model (DOM) on the browser (client) and synchronizing data during client/server communication. ZK shields you from these complexities and lets you focus on the business logic. Other benefits of ZK include:

  • Rich set of user interfaces
  • Web service access
  • Component data binding
  • Simple, but powerful, mark-up language, ZUML
  • Highly maintainable and extensible because there is no client code
  • High usability
  • Improved developer productivity

ZK in action

To understand how ZK works, let's look at a real-world example. This example is a manage customer application through which the user can perform various operations such as adding a new customer, editing the customer data, and soft deletions of the customer entries in the database. But, before diving into the code, I'll explain a few user interface screens that have been generated using ZK. After looking at the screens, I'll describe the architecture of ZK, which is the underlying engine for generating this impressive UI. Finally, I'll describe the code level details along with the configuration parameters used for this application.

Figure 1 shows the initial screen of the manage customer application.

Figure 1. Manage customer index page
Manage Customers application showing a spreadsheet view of the data including ID, Name, Active Date and whether the account is deleted.

Figure 1 shows the list of customers registered within the application. The list is shown as a grid, with columns for an ID, the name of the customer, the active date, and the deleted flag. The data in the grid can be sorted (in either ascending or descending order) by clicking the button near the column names. Sorting has been enabled for the ID (int), Name (String), and active date (Date) column. Later in this article, I'll explain how to customize the sorting using a Comparator object. Pagination has also been enabled for this application, as shown at the bottom of the screen. The page is enabled to show 5 records at a time, along with the ability to move to the next page or directly to a specific page.

Figure 2. The top menu bar
Screenshot of the menu shows Register New Customer and Exit

Figure 2 shows the top bar of the manage customer application. This is implemented using the menubar widget of ZK. It includes an option to register a new customer and exit the application.

Now that you have looked at a couple of user flows of the sample application, let's jump into the architectural details of ZK.

ZK internals

A ZK application behaves similar to a desktop application in that the user activities automatically fire events on the server through the Client Engine. In turn, the components running on the server update the view to match that of the client. The client (browser) just acts as a view, while the application runs on the server and has complete access to resources like databases, Web services, and so on. Consequently, security concerns are minimal.

There are three major components within a ZK framework. As shown in Figure 3, these components are the ZK Client Engine, the ZK Loader, and the ZK Update Engine.

  • ZK Client Engine: This is the client side of ZK, which sends requests to the server to get corresponding ZK responses. These responses, in turn, are used by the engine to update the DOM within the browser.
  • ZK Loader: This component generates an HTML page based on a URL that is requested by the client.
  • ZK Update Engine: This is also known as the Asynchronous Update (AU) Engine. This component is responsible for receiving the Ajax request and updating the corresponding attributes in the ZK component so the Client Engine can update the view on the browser.
Figure 3. The ZK architecture
Architectural drawing of ZK showing the Browser and the Server. The client and server talk to each other through request/response

The mechanism of the flow as described in Figure 3 is as follows:

  • The ZK Loader serves the HTML, including the CSS, JavaScript, and so on, based on the URL requested by the client. This includes the ZK Client Engine, which is responsible for monitoring the client-side events and sending and receiving the ZK Requests and ZK Responses to the server.
  • The Client Engine triggers events based on the user's actions like onChange, onClick, and so on.
  • These events invoke the ZK Update Engine, which updates the properties of the ZK components and responds to the Client Engine.
  • After receiving this response the Client Engine updates the DOM tree within the browser so that the user can see this updated view.

Manage customers using ZK

Next, I'll move on to describing the details of creating a sample application to manage customers. I use the Eclipse IDE to demonstrate the application's creation, but any IDE of your choice should work.

The basic idea is to create a dynamic Web application project and point it to the application server runtime, which in this case is the Apache Tomcat runtime.

After setting up the new project and the runtime, replicate the folder structure as shown in Figure 4.

Figure 4. The directory structure
A package view of zkManageCustomers, src Customer.java and CustomerService.java, then under WebContent addCustomer.zul, editCustomer.zul, index.zul and timeout.zul.

The directory structure of the manage customer application follows the same pattern directory structure as described in Figure 4.

Note that the core of the files for this application are contained within the WebContent folder. Within the WebContent folder I have the following subdirectories:

  • META-INF – This contains the database credential information for connecting to the MySQL database.
  • WEB-INF – This includes the library folder containing the ZK JAR files required for running the application. It also includes the web.xml file, which describes the datasource.
  • In addition, all the associated zul and HTML files are contained within the WebContent folder. These files serve as the view part of the application, providing the dynamic and static content to the Web app.

The sample file zkManageCustomer.zip (see Download) contains the zipped version of the application. It also includes the metadata files required by Eclipse so that it can be imported directly into that IDE seamlessly.

The Java 2 Platform, Enterprise Edition (J2EE) perspective in Eclipse has a server tab, which when right-clicked shows the user an option of creating a new server. This server can be used to manage the application server from the Eclipse IDE.

After the new server is configured, the newly created resources need to be configured on the server. This server configuration deploys the resources that are created during the course of development.


Configuration of Tomcat and MySQL

The example program is configured to work with Tomcat and MySQL. However, you should have no trouble getting it to run in another Java application server, including WebSphere. Since the example uses JDBC, it should work with any supported SQL database, such as DB2 Express-C with only minor changes to the connection code.

To connect Tomcat to the MySQL database you need to define a resource reference. This element specifies the name of a resource manager connection factory reference. In this case, it would be the database connection specified by jdbc/mysql, which is of javax.sql.DataSource type.

Listing 4. Resource manager connection factory in web.xml
	. . .
	<resource-ref>
	      <description>DB Connection</description>
	      <res-ref-name>jdbc/mysql</res-ref-name>
	      <res-type>javax.sql.DataSource</res-type>
	      <res-auth>Container</res-auth>
	</resource-ref>
	. . .

You also need to define a connection resource in the context.xml file under the WebContent/META-INF folder. This file contains properties such as the driver name, jndi name, username, password, datatype, and the URL.

Listing 5. Context definition in context.xml
	. . .
	<Context>
	<Resource driverClassName="com.mysql.jdbc.Driver" 
	maxActive="4" maxIdle="2" maxWait="5000" auth="Container" 
	name="jdbc/mysql" password="" type="javax.sql.DataSource" 
	url="jdbc:mysql://localhost:3306/customer" username="root"/>
	</Context>
	. . .

The customer database has a single table that can be created by running the script shown in Listing 6.

Listing 6. Script to create database
	use customer;
	CREATE TABLE `customer` (
	  `ID` int(11) NOT NULL AUTO_INCREMENT,
	  `name` varchar(255) DEFAULT NULL,
	  `date` date DEFAULT NULL,
	  `deleted` tinyint(1) DEFAULT '0',
	  PRIMARY KEY (`ID`)
	);

Adjusting the application to work with DB2

To connect Tomcat to a DB2-Express C or another DB2 variant database the configuration is very similar to the one described for MySQL. Here is an example showing configuration of the resource manager connection factory in web.xml: . . .

Listing 7. Resource manager connection factory in web.xml
. . .
DB Connection 
jdbc/db2db 
javax.sql.DataSource 
Container 
. . .

For the context definition, a typical example would be as follows: . . .

Listing 8. context definition
. . .
maxActive="4" maxIdle="2" maxWait="5000" auth="Container" 
name="jdbc/db2db" password="" type="javax.sql.DataSource" 
url="jdbc:db2://localhost:(port)/customer" username="db2admin"/>
. . .

Summary of the application

A brief description of the application was presented previously in this article. The manage customers application provides the functions of:

  • Dashboard page enabling user operations, including a view of all customers
  • Adding new customers
  • Editing existing customers
  • Enabling the deletion of customers (Soft delete)

Figure 5 shows the dashboard page of the application. The default view shows the list of customers in the database.

Figure 5. The dashboard screen
Screenshot of the dashboard screen showing a spreadsheet-style layout of data.

The dashboard screen shows a list of all the registered customers. Along with the list of customers, the user also has the ability to sort the data on the basis of either the ID or the Name.

The index.zul file has various attributes such as borderlayout, menubar, menu, and menupopup, all of which define the look and feel of the application.

Listing 9. index.zul file
<menubar id="menubar" width="800px">
 <menu label="Manage Customers">
   <menupopup>
     <menuitem label="Register New Customer">
      <attribute name="onClick"><![CDATA[
        Window win = (Window) Executions.createComponents("addCustomer.zul", null, null);
        win.doModal();
        win.setTitle("Enter Customer Data");
        win.setClosable(true);
        win.setMaximizable(true);
        ]]></attribute>
     </menuitem>
    <menuseparator />
   <menuitem label="Exit" onClick="win.detach()" />
 </menupopup>
</menu>
</menubar>

As shown in Listing 9, I have defined a menubar with a menu label for registering new customers. When this menu is clicked (onClick) I instantiate a Window object through the Executions object using another zul called addCustomer. I also set the attribute for making the dialog modal, closable, and so on. In addition, I include an exit menu that closes the application. The menubar, along with the defined attributes, gives this application a rich-client look and feel.

Listing 10 shows how the table is populated using a listbox element, where I define a model based on which table element is populated.

Listing 10. Sample listbox element defining the table
	<listbox id="customerList" model="@{myList}" mold="paging" pageSize="5"
		multiple="true" width="800px" rows="${custCount}">
	  <listhead sizable="true">
	    <listheader label="Id" sort="auto(id)"/>
	    <listheader label="Name" sort="auto(name)"/>
	    <listheader label="Active Date" sort="auto(date)"/>
	    <listheader label="Deleted?" />
	  </listhead>
	    <listitem self="@{each=myList}" onClick="showEdit(self.getLabel())">
	      <listcell label="@{myList.id}" />
	      <listcell label="@{myList.name}" />
	      <listcell label="@{myList.date}" />
	      <listcell label="@{myList.deleted}"/>
	    </listitem>
	</listbox>

The paging function can be activated using the mold attribute of listbox. Additionally, the sorting based on the column headers can be defined by enabling auto on the sort attribute of the listheader. The myList object is a list of Customer objects, which are composed of attributes such as id, name, date, and the deleted flag of the Customer. The service returns this list, which is then iterated by ZK through the "each =myList". The listcell labels then show each attribute of the customer object in the listbox.

Also, for enabling the edit function I attach a showEdit method to the onClick event.

The register customer dialog is implemented as a grid with mandatory values for the Customer name and Date.

Listing 11. Customer dialog grid code
	<grid fixedLayout="true" width="450px">
	  <rows>
	    <row>
	      <label value="Customer Name" />
	      <textbox id="customerName" constraint="no empty" />
	    </row>
	    <row>
	      <label value="Date" />
	      <datebox id="date" constraint="no empty"/>
	      </row>
	    <row>
	    <button label="Save" onClick="submit()" />
	    <button label="Cancel" onClick="addCustomerWin.detach()" />
	    </row>
	   </rows>
	</grid>

The constraints of mandatory for the dialog is specified using "no empty" as the constraint attribute. ZK also gives you the ability to define custom constraints.

When the Save button is clicked I attach a Java method called submit() to this event. This submit() method receives the name and date value supplied by the user and sets it in a newly created customer object. This object is then passed to the service for adding to the database. Listing 12 shows this code.

Listing 12. Java code for the Save button
void submit() throws Exception {
     Customer cust = new Customer();
     cust.setName(customerName.getValue());
     java.util.Date utilDate = date.getValue();
     java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
     cust.setDate(sqlDate);
     com.test.services.CustomerService custSvc = new com.test.services.CustomerService();
     custSvc.addCustomer(cust);
     Executions.getCurrent().sendRedirect("index.zul");
     addCustomerWin.detach();
}
Figure 6. Register customer
Screenshot shows data entry pop-up for customer with a data authentication message that Customer Name must have a value.

Figure 7 shows a screen to edit the customer's name or date, along with a soft delete option.

Figure 7. Edit/Delete screen
Screenshot of the application with a pop-up data entry screen filled with data and a checkbox

The mechanism to edit is very similar to how you set the register customer code. You pass the new values of name, date, and the deleted flag to the update service for updating the record in the database. If you want to set up additional help, you can use the code in Listing 11 to create a pop-up element.

Listing 13. Code for pop-up element
	<row>
	  <label value="Delete?"/>
	    <hbox>
	      <checkbox id="deleted" name="deleted" checked="${cust.deleted}"/>
	      <label value="whats this?" style="font:9;cursor:help;valign:center"
	       popup="help"/>
	    </hbox>
	    <popup id="help" width="400px">
	    <html>Checking this box will enable soft delete of the record.</html>
	    </popup>
	</row>

Development tools for ZK

The great advantages of ZK are its tools. One example is ZK-Studio (an Eclipse plug-in), which is used as an integrated development environment. It includes features like the ZUL editor, the ZUL Visual editor, the ZK Style designer, and the DB Form builder. Figure 8 shows the ZUL Visual editor, which was used for the creation of this sample project.

Figure 8. ZUL Visual Editor
Screenshot of the ZUL visual editor showing a typical text editor

Summary

This article described features of ZK, an open source Ajax framework written in Java code. The article used a simple real-world example running on Apache Tomcat and connecting to a MySQL database. The ZK framework has a rich set of components, a mark-up language, powerful development tools, and great documentation, along with being open source and an event-driven Ajax framework. Because of all this, ZK is becoming a popular choice for developing low-cost, rich Internet applications.


Download

DescriptionNameSize
Sample applicationzkManageCustomers.zip67KB

Resources

Learn

Get products and technologies

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Web development on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Web development, Open source
ArticleID=456794
ArticleTitle=Rich Internet applications using ZK
publish-date=01052010