From Documentation

Jump to: navigation, search




  • Author
    Robbie Cheng, Technology Evangelist, Potix Corporation
  • Date
    July 27, 2009
  • Version
    ZK 5.0

Contents

Introduction

In the previous article, we introduce both server-centric and client+server fusion approach to build a real-world application – ZK Finance. In this article, we introduce a pure-client centric approach to build the same application.

Creating UI Widgets using iZUML (Markup language)

Since ZK 5, developers can use versatile ZK widgets using client-side programming, either JavaScript or iZUML. No server object will be created. Developers can ease the loading of servers, and leverage the computing power of clients at the same time.

In the article, we will turn all widgets into pure-client widgets using iZUML, including search box, search result, historical price, and the chart diagram. First of all, we have to including JavaScript libraries of ZK into the page.

<script type="text/javascript" src="/zkdemo/zkau/web/js/zk.wpd" charset="UTF-8">
</script>
<script type="text/javascript" src="/zkdemo/zkau/web/js/zk.zuml.wpd" charset="UTF-8">
</script>

Then, we use iZUML to create the search box, and search result. It is intuitive, and easy to learn. Moreover, ZK developers can share the same programming experience. One thing to notice is that we have to comment the code in case it will be processed by browser directly.

<div id="main">
<!--
<page>
	<borderlayout id="main">
		<west title="ZK Finance" size="250px" flex="true"
			splittable="true" minsize="210" maxsize="500" collapsible="true">
			<panel>
				<toolbar>
					<label value="Search:" />
					<textbox id="searchBox"/>
				</toolbar>
				<panelchildren>
					<listbox id="itemList"
						fixedLayout="true" vflex="true">									
						<listitem forEach="${_.items}" uuid="${each.id}" label="${each.label}" />
					</listbox>
				</panelchildren>
			</panel>
		</west>
		<center>
			<div id="detail"/>
		</center>
	</borderlayout>
</page> 
-->
</div>

Besides, we use grid component to represent the historical data of stocks as follows:

<div id="history" style="display:none">
<!--
<div id="history">
	<grid fixedLayout="true">
		<columns menupopup="auto">
			<column label="Date" />
			<column label="Open" />
			<column label="High" />
			<column label="Low" />
			<column label="Close" />
			<column label="Volumn" />
		</columns>
		<rows>
			<row forEach="${_.infos}">
				<label value="${each.date}"/>
				<label value="${each.open}"/>
				<label value="${each.high}"/>
				<label value="${each.low}"/>
				<label value="${each.close}"/>
				<label value="${each.volumn}"/>
			</row>
		</rows>
	</grid>
	<div id="chart" style="margin-top:20px; margin-left:20px; width:700px; height:250px"></div>
</div>
 -->
</div>

ZK Parser and Event Listeners

Secondly, to turn the above code into widgets, we use the ZK Parser to parse it into widgets, and then, we register required event listeners at the same time as follows:

zk.zuml.Parser.createAt('#main', null, {items: data}, function (page) {
	var itemList = win.$f('itemList'),
	      detail = win.$f('detail'),
	      searchBox = win.$f('searchBox');
	
	//register onChaning event listener
	win.$f('searchBox').listen({onChanging: function (event) {
			update(itemList, event.data.value);
	}});


	// select the first item by default.
	itemList.firstItem.setSelected(true);
	itemList.fireOnSelect(itemList.firstItem, {data: null});
	searchBox.focus();
});

Asynchronous communication with the Server

Once users select any stock, we have to get its historical data from the server to display it. In this article, we use jQuery’s Ajax utility as an example to send the a POST request to the server once users selects any stock item from the search result. Moreover, we register a callback function to update the table and chart once data is send back from the server.

itemList.listen({onSelect: function (event) {
 jq.ajax({
	   type: 'POST',
	   url:'stockinfo',
	   dataType: 'json',
	   data: 'stockId=' + event.data.items[0],
	   success: function (priceInfo) {
			var history = zk.Widget.$('history');
			if (history) history.detach();
			zk.zuml.Parser.createAt('#history', {replaceHTML:false}, {infos: priceInfo}, function (wgt) {
				detail.appendChild(wgt);
				createChart(wgt.$f('chart').uuid, getChartData(priceInfo));
			});
		}
	 });
}});

Next, we shall provide a backend service which provides the historical data of stocks. Basically, developers can choose their preferred backend technology to interact with the client. Here, we use Java Servlet as an example. We create a PriceServlet.java at the server which returns the data once it receives an onSelect command from the client as follows:

public class StockServlet extends HttpServlet {
	private Map _stockInfos;
	private static DateFormat _sdfFrom = new SimpleDateFormat("dd-MMM-yy", Locale.ENGLISH);
	private static SimpleDateFormat _sdfTo = new SimpleDateFormat("yyyy/MM/dd");	
        .....
	
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doPost(req, resp);
	}
	
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		if ("onSelect".equals(req.getParameter("event"))) {
			String stockId = req.getParameter("stockId");
			resp.getWriter().append(JSONArray.toJSONString((List)_stockInfos.get(stockId)));
		}
	}
}

Summary

Since ZK 5, developers can leverage 200+ versatile ZK widgets using either JavaScript or iZUML. And pure-client centric approach allows developer to integrate with any server-side technologies. Moreover, developers can leverage the client』s computing power to improve the responsiveness of their Web application. However, the disadvantage of applying this optional client-side programming is that it requires more jobs to implement such a simple function than pure server-centric approach.

Download

The application could be downloaded here.




Copyright © Potix Corp. This article is licensed under GNU Free Documentation License.
You got stuck here?
Let us know how we can improve this page
For specific questions please use the forum