Creating a Simple Sightseeing Application"

From Documentation
Line 230: Line 230:
 
#:Unzip resort.zip, and copy resort.war to $TOMCAT_HOME/webapps/.
 
#:Unzip resort.zip, and copy resort.war to $TOMCAT_HOME/webapps/.
 
#Start your Web Server, and point your browser to: http://localhost:8080/resort/resort.zul
 
#Start your Web Server, and point your browser to: http://localhost:8080/resort/resort.zul
 +
 +
----
 +
Last Update : {{REVISIONYEAR}}/{{REVISIONMONTH}}/{{REVISIONDAY}}

Revision as of 10:34, 29 September 2010

Before You Start

Translations are available in Français and Español.

Other resources

Introduction

This tutorial aims to use a small sample application to demonstrate the strengths of ZK..

We'll show two ways to build an Ajax-enabled web application using ZK: a standard way that does not use ZK's data binding features, and an advanced way that uses ZK's data binding features.

Our sample application is a sightseeing web site that uses Google Maps. Its web page has three parts, a table on the left side, a Google Maps on the right side, and a pane on the bottom of the page. You could try the application on line.

Resort-s.jpg

  • Ajax in Action: When a user selects an item in the table, the location of that item will display on the Google Maps, and its coordinates will be shown on the bottom pane.

The Data Model

The data model for this application is simple; it consists of the following four attributes: name, description, latitude, and longitude.

public class Resort {
 private String _name;
 private String _description;
 private Double _latitude;
 private Double _longitude;
 
 public Resort(){};
 public Resort(String name, String description, Double latitude, Double longitude) {
  _name = name;
  _description = description;
  _latitude = latitude;
  _longitude = longitude;
 }
 // getter and setter methods are omitted.
 }

A Straightforward Way (Without Data Binding)

First, let's show a simple way to use and experience the strengths of ZK, without the trappings of ZK's details.

Design User Interface Page Using ZK Markup Language

We first develop the application's view page file: resort.zul; it includes a listbox (table), a gmaps(Google Maps), and a groupbox(pane).

Notice how simple and clean resort.zul is -- no java codes or scriplets, all handler codes are defined in a separate Java file — ResortController.java.

The interaction between the zul file and the Java file is triggered by a user's activities. When a user selects an item in the listbox, the onSelect event of the listbox will be fired, and the refreshUI() method of ResortController.java will be invoked to display the selected item on the Google Maps, and to show the coordinates of selected item.

<!-- resort.zul -->
<window id="win" use="org.zkforge.resort.ui.ResortController" title="ZK Tutorial" width="1024px" border="normal">
<script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAACZ90QS5pNiEvbXhI0k2NLRTGXUEQDrMr1bP0DVG
8X36ZVCheaRQMK05Rsdneh4skNF6KXaLI8maLlA" type="text/javascript"/>
 <hbox>
<listbox id="lb" onSelect="win.refreshUI()">
  <listhead sizable="true">
   <listheader label="Name" width="100px"/>
   <listheader label="Description" width="250px"/>   
  </listhead>
  <listitem forEach="${win.resorts}" value="${each}">
   <listcell label="${each.name}" />
   <listcell label="${each.description}" />   
  </listitem>
 </listbox>
<gmaps id="gmap" zoom="16" showTypeCtrl="true" mapType="satellite" showLargeCtrl="true" width="610px" 
 height="400px">
  <ginfo id="ginfo"/>
 </gmaps>
 </hbox>
<groupbox mold="3d" width="100%">
  <caption label="Resort"/>
  Name:       <textbox id="name" disabled="true"/>
  Description:<textbox id="desc" disabled="true"/> 
  Latitude:   <doublebox id="lat" disabled="true"/>
  Longitude:  <doublebox id="lng" disabled="true"/>
 </groupbox> 
</window>

Manipulate UI Components Using Java

In the Java file(ResortController.java), we retrieve the UI components by their id, and put the data of the selected item into them. Then, ZK engines will update the web page in Ajax automatically.

<!--ResortController.java -->
public class ResortController extends Window { 
 List _resorts = new ArrayList();
  
 public ResortController(){
  _resorts.add(new Resort("La Tour Eiffel",
    "Insolite ! Découvrez la Tour Eiffel autrement.",48.8585599391,2.2945332527));
  _resorts.add(new Resort("Buckingham Palace",
    "The official London residence of the sovereign.",51.5013698182,-0.1416689157));
  _resorts.add(new Resort("東京タワ",
    "総數4萬の光ファンタジーと都內最大級15mのツリー!",35.6583487578,139.7457217178));
  _resorts.add(new Resort("Der Kölner Dom",
    "Offizieller Name Hohe Domkirche St. Peter und Maria",50.9414206771,6.9586372375));
 }
  
 public void refreshUI(){
  Listbox lb = (Listbox) getFellow("lb");
  Resort resort = (Resort) lb.getSelectedItem().getValue();
  ((Textbox)getFellow("name")).setValue(resort.getName());
  ((Textbox)getFellow("desc")).setValue(resort.getName());
  ((Doublebox)getFellow("lat")).setValue(resort.getLatitude());
  ((Doublebox)getFellow("lng")).setValue(resort.getLongitude());
  
  Gmaps gmap = (Gmaps) getFellow("gmap");
  Ginfo ginfo = (Ginfo) getFellow("ginfo");
  ginfo.setLat(resort.getLatitude());
  ginfo.setLng(resort.getLongitude());
  ginfo.setContent(resort.getDescription());
  gmap.panTo(resort.getLatitude(),resort.getLongitude());
  gmap.setZoom(16);
  gmap.openInfo(ginfo);
 }
 public List getResorts() {
  return _resorts;
 }
 public void setResorts(List resorts) {
  _resorts = resorts;
 }
}

This example illustrates the simplicity of building an Ajax-enabled web application with ZK. The "View" and "Controller" are cleanly separated, and no JavaScript code is required! We believe that the best way to use Ajax is to not have to know of its existence.

An Automatic Way (With Data Binding)

To simplify the job of maintaining the consistency of data between the data bean and the user interface, ZK provides the mechanism of data-binding. You simply define the relations between the "Model" (data beans) and the "View" (UI components), and ZK's data-binding feature will maintain the data consistency between them automatically.

Define Relations between Data Bean and UI Components

One simple way is to directly define such relations in the web page. One of the major differences is that we add another data bean which represents the selected item, and then bind all of related ZK components to it.

    <!-- resort_databind.zul -->
    <?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
    <window id="win" use="org.zkforge.resort.ui.ResortController2" title="ZK Tutorial" width="1024px" border="normal">
    <script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAACZ90QS5pNiEvbXhI0k2NLRTGXUEQDrMr1bP0DVG
    8X36ZVCheaRQMK05Rsdneh4skNF6KXaLI8maLlA"  type="text/javascript"/>
     <hbox>
    <listbox model="@{win.resorts}" selectedItem="@{win.selected}" onSelect="win.refreshUI()">
      <listhead sizable="true">
       <listheader label="Name" width="100px"/>
       <listheader label="Description" width="250px"/>   
      </listhead>
      <listitem self="@{each=resort}">
       <listcell label="@{resort.name}" />
       <listcell label="@{resort.description}" />   
      </listitem>
     </listbox> 
     <gmaps id="gmap" zoom="16" showTypeCtrl="true" mapType="satellite" showLargeCtrl="true" width="610px" 
      height="400px">
      <ginfo id="ginfo" lng="@{win.selected.longitude}" lat="@{win.selected.latitude}"
      content="@{win.selected.description}"/>
     </gmaps>
     </hbox>
     <groupbox id="gb" mold="3d" width="100%">
      <caption label="Resort"/>
      Name:<textbox id="name" value="@{win.selected.name}" disabled="true"/>
      Description:<textbox  id="desc" value="@{win.selected.description}" disabled="true"/> 
      Latitude:<doublebox id="lat" value="@{win.selected.latitude}" disabled="true"/>
      Longitude:<doublebox id="lng" value="@{win.selected.longitude}" disabled="true"/>  
     </groupbox>
    </window>

Revise the Java File

With the help of data-binding, the handling codes in ResortController.java are much reduced. Once the user selects a different item, the data bean will be changed, and then data of all related ZK components will be updated automatically.

    <!--ResortController2.java --> 
     
    public class ResortController extends Window { 
     List _resorts = new ArrayList();  
     Resort _selected = new Resort();
     
     public ResortController(){
       _resorts.add(new Resort("La Tour Eiffel",
        "Insolite ! Découvrez la Tour Eiffel autrement.",48.8585599391,2.2945332527));
      _resorts.add(new Resort("Buckingham Palace",
        "The official London residence of the sovereign.",51.5013698182,-0.1416689157));
      _resorts.add(new Resort("東京タワ",
        "総數4萬の光ファンタジーと都內最大級15mのツリー!",35.6583487578,139.7457217178));
      _resorts.add(new Resort("Der Kölner Dom",
        "Offizieller Name Hohe Domkirche St. Peter und Maria",50.9414206771,6.9586372375));
     }
      
     public void refreshUI(){  
      Gmaps gmap = (Gmaps) getFellow("gmap");
      Ginfo ginfo = (Ginfo) getFellow("ginfo");  
      gmap.panTo(ginfo.getLat(),ginfo.getLng());
      gmap.setZoom(16);
      gmap.openInfo(ginfo);
     }
     public List getResorts() {
      return _resorts;
     }
     public void setResorts(List resorts) {
      _resorts = resorts;
     }
     public Resort getSelected() {
      return _selected;
     }
     public void setSelected(Resort selected) {
      _selected = selected;
     }
    }

Installing the Web Application

  1. Install Java SDK
    If you haven't already done so, please download and install the Java SDK SUN Java Standard SDK.
  2. Install a Servlet Container
    If you don't already have a Servlet container, please download and install Apache Tomcat.
  3. Download the Web Application
    Download this application's files here.
  4. Unzip the file
    Unzip resort.zip, and copy resort.war to $TOMCAT_HOME/webapps/.
  5. Start your Web Server, and point your browser to: http://localhost:8080/resort/resort.zul

Last Update : 2010/09/29