Getting Started with ZK - Part 2
The Persistent Layer
In the following paragraphs, the database schema, domain object, and DAO object will be introduced.DataBase Schema
A database table to hold our application data would need the following attributes: event id, event name, event priority ,and event date. The database schema is listed below.
Field Type id varchar(50) name varchar(50) priority int date date Domain Object
For the above table, we create a corresponding domain object, as follows:public class Event { private String id; private String name; private int priority; private Date date; public Event(){} public Event(String id,String name,int priority,Date date){ this.id = id; this.name = name; this.priority = priority; this.date = date; } //getter and setter methods are ommited, please refer to the source code. }DAO Object
In order to easily access the data in our database we need a DAO object with the following methods:findAll(),delete(),insert(),and update().public class EventDAO { private String url = "jdbc:hsqldb:file:/hsqldb/event"; private String user = "sa"; private String pwd = ""; public EventDAO() { try { Class.forName("org.hsqldb.jdbcDriver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } //The implementation is ommited, please refer to the source code. public List findAll(){} public boolean delete(Event evt){} public boolean insert(Event evt){} public boolean update(Event evt){} }
Interaction between UI, and the Database
According to our requirements, we want to be able to display events, add, edit, and delete an event. In the following paragraphs, we are going to implement the interaction between our web application page and the application's database.Using Java Code to Interact with ZK Components
One of the most fancy characteristics of ZK is that you could use Java code to interact with ZK Components defined in a page. ZK provides you three options: embed the Java code directly in the page; put the Java code in a separate file; or interact with the page using pure compiled Java classes. However, we will focus on the first option in this tutorial for better explanation.Embedding Java Code into the Page
First, we have to load event data from our database, and we could embed Java code into this page by declaring a pair of enclosing <zscript> tags.
The zscript element is a special element for defining scripting codes that will be evaluated each time a ZUL page is rendered. It is typically used for initialization, and for declaring global variables and methods. We'll declare an instance of eventDAO for database access, and we'll store the query result into a
List.Global variables defined within a zscript element could be accessed by using El-expression. As in JSP, you could use El-expressions in any part of a ZUML page, and the syntax for EL expressions is: ${expr}.
The initialization of database access is as follows:
<window title="To do list" width="640px" border="normal"> <zscript> import events.Event; import events.EventDAO; import java.util.ArrayList; //fetch all events from database EventDAO evtdao = new EventDAO(); List allEvents = evtdao.findAll(); </zscript> <listbox id="box" multiple="true" rows="4"> <listhead> <listheader label="Item" /> <listheader label="Priority" width="50px" /> <listheader label="Opened" width="90px" /> </listhead> <listitem> <listcell/> <listcell/> <listcell/> </listitem> </listbox> <groupbox> <caption label="New" /> Item: <textbox id="name" cols="50" /> Priority: <intbox id="priority" cols="1" /> Date: <datebox id="date" cols="8"> <button label="Add" width="36px" height="24px"/> <button label="Update" width="46px" height="24px"/> <button label="Delete" width="46px" height="24px"/> </groupbox> </window>Using forEach loop
The next step is to render data stored in an allEvents variable into the
listboxcomponent using a forEach loop within the listitem component. The forEach attribute is used to control the number of components that should be created.If you specify a collection of objects to it, ZK Loader will create a corresponding number of components according to the specified collection. And, the each variable represents an object instance stored in the collection. We could use El-expressions to invoke getter methods of the object to retrieve its attributes as follows:
<window title="To do list" width="640px" border="normal"> <zscript> import events.Event; import events.EventDAO; import java.util.ArrayList; //fetch all events from database EventDAO evtdao = new EventDAO(); List allEvents = evtdao.findAll(); </zscript> <listbox id="box" multiple="true" rows="4"> <listhead> <listheader label="Item" /> <listheader label="Priority" width="50px" /> <listheader label="Opened" width="90px" /> </listhead> <listitem forEach="${allEvents}" value="${each}"> <listcell label="${each.name}" /> <listcell label="${each.priority}" /> <listcell label="${each.date}" /> </listitem> </listbox> <groupbox> <caption label="New" /> Item: <textbox id="name" cols="50" /> Priority: <intbox id="priority" cols="1" /> Date: <datebox id="date" cols="8"> <button label="Add" width="36px" height="24px"/> <button label="Update" width="46px" height="24px"/> <button label="Delete" width="46px" height="24px"/> </groupbox> </window>
Save User's Input Data into Database
First, let's try to declare an add() method within the enclosing tags of <zscript>.In the<zscript> .... void add(){} </zscript>add()method, we have to complete the following three tasks,
- Retrieve User's Input Data
- Save Data into Database
- Refresh the View in Ajax
Retrieve User's Input Data
ZK allows you to access UI components in Java code. You could access a component by its identifier specified in its id attribute. In this example, user's input data are stored in three input components, textbox(id ="name"), intbox(id ="priority"), and datebox(id="date"). Thus, we could get user's input data by accessing the value attribute of these components, as follows:
name.value; //event name priority.value; //event priority date.value; //event dateSave Data into Database
Once we've retrieved user's input data we can save it into our database simply as follows:
Event newEvt = new Event(UUID.randomUUID().toString(),name.value,priority.value.intValue(),date.value); evtdao.insert(newEvt); //synchronized data object with database allEvents = evtdao.findAll();Refresh the View in Ajax
Incredibly, ZK allows you to refresh the view in Ajax simply by using Java code. In this case, we insert a new listitem into the
listboxin Java code as follows, and the job of refreshing the page is handled by ZK automatically.
//insert a new Event into the listbox Listitem li = new Listitem(); li.setValue(newEvt); li.appendChild(new Listcell(name.value)); li.appendChild(new Listcell(priority.value)); li.appendChild(new Listcell(new SimpleDateFormat("yyyy-MM-dd").format(date.value))); box.appendChild(li);
- appendChild(), to insert a child component into itself
The complete code is listed below,
<window title="To do list" width="640px" border="normal"> <zscript> import events.Event; import events.EventDAO; import java.util.ArrayList; import java.text.SimpleDateFormat; import java.util.UUID; //fetch all events from database EventDAO evtdao = new EventDAO(); List allEvents = evtdao.findAll(); void add(){ //insert into database Event newEvt = new Event(UUID.randomUUID().toString(),name.value,priority.value.intValue(),date.value); evtdao.insert(newEvt); //synchronized data object with database allEvents = evtdao.findAll(); //insert a new Event into the listbox Listitem li = new Listitem(); li.setValue(newEvt); li.appendChild(new Listcell(name.value)); li.appendChild(new Listcell(priority.value)); li.appendChild(new Listcell(new SimpleDateFormat("yyyy-MM-dd").format(date.value))); box.appendChild(li); } </zscript> <listbox id="box" multiple="true" rows="4"> <listhead> <listheader label="Item" /> <listheader label="Priority" width="50px" /> <listheader label="Opened" width="90px" /> </listhead> <listitem forEach="${allEvents}" value="${each}"> <listcell label="${each.name}" /> <listcell label="${each.priority}" /> <listcell label="${each.date}" /> </listitem> </listbox> <groupbox> <caption label="New" /> Item: <textbox id="name" cols="50" /> Priority: <intbox id="priority" cols="1" /> Date: <datebox id="date" cols="8"> <button label="Add" width="36px" height="24px"/> <button label="Update" width="46px" height="24px"/> <button label="Delete" width="46px" height="24px"/> </groupbox> </window>Register Event Listener in ZK Components
Almost 90% of the reaction from a page is triggered by user’s activities. The
add()method is no exception, and it should be invoked only when the user presses the “add” button. The way to determine whether or not this button is clicked by the user is to declare an onClick event listener within the declaration of thebuttoncomponent, and specify the add() method in this onClick event listener.ZK will invoke the add() method if this button is clicked by a user. Quite intuitive, right? Again! ZK provides the simplest way for you.
<button label="Add" width="36px" height="24px" onClick="add()" />Other Control Codes
The rest of the control codes are listed below,
delete(), delete an event from database, updating the data model, andlistbox.update(), update an event from database, updating the data model, andlistbox.move(), move data fromlistboxto input components in the group boxcleargp(), clear data of input components in the group box<zscript> import events.Event; import events.EventDAO; import java.util.ArrayList; import java.text.SimpleDateFormat; import java.util.UUID; //fetch all events from database EventDAO evtdao = new EventDAO(); List allEvents = evtdao.findAll(); void add(){ //insert into database Event newEvt = new Event(UUID.randomUUID().toString(), name.value,priority.value.intValue(),date.value); evtdao.insert(newEvt); //synchronized data with database allEvents = evtdao.findAll(); //insert a listEvent into the listbox Listitem li = new Listitem(); li.setValue(newEvt); li.appendChild(new Listcell(name.value)); li.appendChild(new Listcell(priority.value.toString())); li.appendChild(new Listcell(new SimpleDateFormat("yyyy-MM-dd").format(date.value))); box.appendChild(li); } void update(){ //update database Event editEvt = (Event)box.selectedItem.value; editEvt.setName(name.value); editEvt.setPriority(priority.value); editEvt.setDate(date.value); evtdao.update(editEvt); //update listbox List children = box.selectedItem.children; ((Listcell)children.get(0)).label = name.value; ((Listcell)children.get(1)).label = priority.value.toString(); ((Listcell)children.get(2)).label = new SimpleDateFormat("yyyy-MM-dd").format(date.value); } void delete(){ evtdao.delete((Event)box.selectedItem.value); box.removeItemAt(box.getSelectedIndex()); cleargb(); } void move(){ name.value = ((Event)box.selectedItem.value).getName(); priority.value = ((Event)box.selectedItem.value).getPriority(); date.value = ((Event)box.selectedItem.value).getDate(); } void cleargb(){ name.value = null; priority.value = null; date.value = null; } </zscript>Register Corresponding Event Listeners
The last step is to register corresponding event listeners in ZK components to invoke those methods.
- Register
onClickevent listener in delete button- Register
onClickevent listener in edit button- Register
onSelectevent listener inlistbox<window title="To do list" width="640px" border="normal"> <zscript> //the implementation part is ommited, please refer to the above listing. void add(){} void delete(){} void update(){} void move(){} void cleargb(){} </zscript> <listbox id="box" multiple="true" rows="4" onSelect="move()"> <listhead> <listheader label="Item" /> <listheader label="Priority" width="50px" /> <listheader label="Opened" width="90px" /> </listhead> <listitem forEach="${allEvents}" value="${each}"> <listcell label="${each.name}" /> <listcell label="${each.priority}" /> <listcell label="${each.date}" /> </listitem> </listbox> <groupbox> <caption label="Event" /> Item: <textbox id="name" cols="25" /> Priority: <intbox id="priority" cols="1" /> Date: <datebox id="date" cols="8" /> <button label="Add" width="36px" height="24px" onClick="add()" /> <button label="Update" width="46px" height="24px" onClick="update()" /> <button label="Delete" width="46px" height="24px" onClick="delete()" /> </groupbox> <window>
Summary
This tutorial has covered the basics of writing a simple web application with ZK.
Further readings are listed below.- Using IDE to develop ZK Applications
- Integrate ZK with other Frameworks
- Work with Legacy Web Applications
- Enrich the Layout of Components
- Q&A
- If you encounter any problem with ZK, please report it in ZK forum
.









