You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2007/06/19 02:53:05 UTC

svn commit: r548539 - in /tapestry/tapestry5/trunk/tapestry-tutorial1/src: main/java/org/apache/tapestry/tutorial/data/ main/java/org/apache/tapestry/tutorial/pages/address/ main/resources/org/ main/resources/org/apache/ main/resources/org/apache/tapes...

Author: hlship
Date: Mon Jun 18 17:53:03 2007
New Revision: 548539

URL: http://svn.apache.org/viewvc?view=rev&rev=548539
Log:
Chapter 4: Forms

Added:
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/Address.java
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/Honorific.java
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/address/
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/address/CreateAddress.java
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/resources/org/
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/resources/org/apache/
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/resources/org/apache/tapestry/
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/resources/org/apache/tapestry/tutorial/
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/resources/org/apache/tapestry/tutorial/pages/
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/resources/org/apache/tapestry/tutorial/pages/address/
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/resources/org/apache/tapestry/tutorial/pages/address/CreateAddress.properties
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/webapp/WEB-INF/address/
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/webapp/WEB-INF/address/CreateAddress.html
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/site/resources/address-v1.png   (with props)
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/site/resources/address-v2.png   (with props)
Modified:
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/webapp/WEB-INF/Start.html
    tapestry/tapestry5/trunk/tapestry-tutorial1/src/site/apt/forms.apt

Added: tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/Address.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/Address.java?view=auto&rev=548539
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/Address.java (added)
+++ tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/Address.java Mon Jun 18 17:53:03 2007
@@ -0,0 +1,124 @@
+package org.apache.tapestry.tutorial.data;
+
+public class Address
+{
+  private Honorific _honorific;
+
+  private String _firstName;
+
+  private String _lastName;
+
+  private String _street1;
+
+  private String _street2;
+
+  private String _city;
+
+  private String _state;
+
+  private String _zip;
+
+  private String _email;
+
+  private String _phone;
+
+  public Honorific getHonorific()
+  {
+    return _honorific;
+  }
+
+  public String getFirstName()
+  {
+    return _firstName;
+  }
+
+  public String getLastName()
+  {
+    return _lastName;
+  }
+
+  public String getStreet1()
+  {
+    return _street1;
+  }
+
+  public String getStreet2()
+  {
+    return _street2;
+  }
+
+  public String getCity()
+  {
+    return _city;
+  }
+
+  public String getState()
+  {
+    return _state;
+  }
+
+  public String getZip()
+  {
+    return _zip;
+  }
+
+  public String getEmail()
+  {
+    return _email;
+  }
+
+  public String getPhone()
+  {
+    return _phone;
+  }
+
+  public void setCity(String city)
+  {
+    _city = city;
+  }
+
+  public void setEmail(String email)
+  {
+    _email = email;
+  }
+
+  public void setFirstName(String firstName)
+  {
+    _firstName = firstName;
+  }
+
+  public void setHonorific(Honorific honorific)
+  {
+    _honorific = honorific;
+  }
+
+  public void setLastName(String lastName)
+  {
+    _lastName = lastName;
+  }
+
+  public void setPhone(String phone)
+  {
+    _phone = phone;
+  }
+
+  public void setState(String state)
+  {
+    _state = state;
+  }
+
+  public void setStreet1(String street1)
+  {
+    _street1 = street1;
+  }
+
+  public void setStreet2(String street2)
+  {
+    _street2 = street2;
+  }
+
+  public void setZip(String zip)
+  {
+    _zip = zip;
+  }
+}

Added: tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/Honorific.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/Honorific.java?view=auto&rev=548539
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/Honorific.java (added)
+++ tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/data/Honorific.java Mon Jun 18 17:53:03 2007
@@ -0,0 +1,6 @@
+package org.apache.tapestry.tutorial.data;
+
+public enum Honorific
+{
+  MR, MRS, MISS, DR
+}

Added: tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/address/CreateAddress.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/address/CreateAddress.java?view=auto&rev=548539
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/address/CreateAddress.java (added)
+++ tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/java/org/apache/tapestry/tutorial/pages/address/CreateAddress.java Mon Jun 18 17:53:03 2007
@@ -0,0 +1,19 @@
+package org.apache.tapestry.tutorial.pages.address;
+
+import org.apache.tapestry.tutorial.data.Address;
+
+public class CreateAddress
+{
+  private Address _address;
+
+  public Address getAddress()
+  {
+    return _address;
+  }
+
+  public void setAddress(Address address)
+  {
+    _address = address;
+  }
+
+}

Added: tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/resources/org/apache/tapestry/tutorial/pages/address/CreateAddress.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/resources/org/apache/tapestry/tutorial/pages/address/CreateAddress.properties?view=auto&rev=548539
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/resources/org/apache/tapestry/tutorial/pages/address/CreateAddress.properties (added)
+++ tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/resources/org/apache/tapestry/tutorial/pages/address/CreateAddress.properties Mon Jun 18 17:53:03 2007
@@ -0,0 +1 @@
+foo=Foo Bar Baz Baby!

Modified: tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/webapp/WEB-INF/Start.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/webapp/WEB-INF/Start.html?view=diff&rev=548539&r1=548538&r2=548539
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/webapp/WEB-INF/Start.html (original)
+++ tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/webapp/WEB-INF/Start.html Mon Jun 18 17:53:03 2007
@@ -12,5 +12,11 @@
       <t:actionlink>Start guessing</t:actionlink>
     </p>
 
+    <h1>Address Book</h1>
+
+    <ul>
+      <li><t:pagelink page="address/create">Create new address</t:pagelink></li>
+    </ul>
+
   </body>
 </html>

Added: tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/webapp/WEB-INF/address/CreateAddress.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/webapp/WEB-INF/address/CreateAddress.html?view=auto&rev=548539
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/webapp/WEB-INF/address/CreateAddress.html (added)
+++ tapestry/tapestry5/trunk/tapestry-tutorial1/src/main/webapp/WEB-INF/address/CreateAddress.html Mon Jun 18 17:53:03 2007
@@ -0,0 +1,12 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <head>
+    <title>Create New Address</title>
+  </head>
+  <body>
+
+    <h1>Create New Address</h1>
+
+    <t:beaneditform object="address"/>
+
+  </body>
+</html>

Modified: tapestry/tapestry5/trunk/tapestry-tutorial1/src/site/apt/forms.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-tutorial1/src/site/apt/forms.apt?view=diff&rev=548539&r1=548538&r2=548539
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-tutorial1/src/site/apt/forms.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-tutorial1/src/site/apt/forms.apt Mon Jun 18 17:53:03 2007
@@ -4,4 +4,297 @@
  
 Chapter 4: Forms in Tapestry
 
-  <Coming soon!>
\ No newline at end of file
+  In the previous chapters, we saw how Tapestry can handle simple links, even links that pass information in the URL. In this chapter,
+  we'll see how Tapestry can do the same, and quite a bit more, for HTML forms.  
+  
+  Form support in Tapestry is deep and rich, more than can be covered in a single chapter. However, we can show the basics, including
+  some very common development patterns. To get started, let's create a simple address book application.
+  
+  We'll start with the data, a simple object to store the information we'll need. By convention, these classes go in a <<<data>>> sub-package.  Unlike
+  the use of the <<<pages>>> sub-package (for page component classes), this is not enforced by Tapestry; it's just a convention.
+  
+  
+  <<src/main/java/org/apache/tapestry/tutorial/data/Address.java:>>
+  
+----
+package org.apache.tapestry.tutorial.data;
+
+public class Address
+{
+  private Honorific _honorific;
+
+  private String _firstName;
+
+  private String _lastName;
+
+  private String _street1;
+
+  private String _street2;
+
+  private String _city;
+
+  private String _state;
+
+  private String _zip;
+
+  private String _email;
+
+  private String _phone;
+
+  public String getCity()
+  {
+    return _city;
+  }
+
+  public String getEmail()
+  {
+    return _email;
+  }
+
+  public String getFirstName()
+  {
+    return _firstName;
+  }
+
+  public Honorific getHonorific()
+  {
+    return _honorific;
+  }
+
+  public String getLastName()
+  {
+    return _lastName;
+  }
+
+  public String getPhone()
+  {
+    return _phone;
+  }
+
+  public String getState()
+  {
+    return _state;
+  }
+
+  public String getStreet1()
+  {
+    return _street1;
+  }
+
+  public String getStreet2()
+  {
+    return _street2;
+  }
+
+  public String getZip()
+  {
+    return _zip;
+  }
+
+  public void setCity(String city)
+  {
+    _city = city;
+  }
+
+  public void setEmail(String email)
+  {
+    _email = email;
+  }
+
+  public void setFirstName(String firstName)
+  {
+    _firstName = firstName;
+  }
+
+  public void setHonorific(Honorific honorific)
+  {
+    _honorific = honorific;
+  }
+
+  public void setLastName(String lastName)
+  {
+    _lastName = lastName;
+  }
+
+  public void setPhone(String phone)
+  {
+    _phone = phone;
+  }
+
+  public void setState(String state)
+  {
+    _state = state;
+  }
+
+  public void setStreet1(String street1)
+  {
+    _street1 = street1;
+  }
+
+  public void setStreet2(String street2)
+  {
+    _street2 = street2;
+  }
+
+  public void setZip(String zip)
+  {
+    _zip = zip;
+  }
+}
+----
+
+  It's just a collection of getter and setter methods.  We also need to define the enum type, Salutation:
+  
+  <<src/main/java/org/apache/tapestry/tutorial/data/Honorific.java:>>
+  
+---
+package org.apache.tapestry.tutorial.data;
+
+public enum Honorific
+{
+  MR, MRS, MISS, DR
+}
+---
+
+* Address Pages
+
+  We're probably going to create a few pages related to addresses: pages for creating them, for editting them, for searching and listing them.
+  We'll create a sub-folder, address, to hold them.  Let's get started on the first of these pages, "address/Create"  (that's the real name, including
+  the slash --- we'll see in a minute how that maps to classes and templates).
+  
+  First, we'll update the Start.html template, to create a link for creating a new page:
+  
+  <<src/main/webapp/WEB-INF/Start.html:>>
+
+----
+    <h1>Address Book</h1>
+
+    <ul>
+      <li><t:pagelink page="address/create">Create new address</t:pagelink></li>
+    </ul>
+----
+
+   Now we need the page, let's start with an empty shell, just to test our navigation.
+  
+  <<src/main/webapp/WEB-INF/address/CreateAddress.html:>>
+  
+---
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <head>
+    <title>Create New Address</title>
+  </head>
+  <body>
+
+    <h1>Create New Address</h1>
+
+    <em>coming soon ...</em>
+
+  </body>
+</html>
+---
+
+  And the corresponding class:
+  
+  <<src/main/java/org/apache/tapestry/tutorial1/pages/address/CreateAddress.java:>>
+  
+----
+package org.apache.tapestry.tutorial.pages.address;
+
+public class CreateAddress
+{
+
+}
+----
+   
+   So ... why is the class named "CreateAddress" and not simply "Create"?  Actually, we could have, and it would work.  Tapestry noticed the redundancy in the
+   class name:  <<<org.apache.tapestry.tutorial1.pages.>>><address><<<.Create>>><Address> and just stripped it out.
+   
+   Eventually, your application will probably have more entities:  perhaps you'll have a "create/User" page and a "create/Payment" page and a "create/Account" page.
+   Now, you <could> have a bunch of different classes named <<<Create>>> spread across a number of different packages.  That's legal Java, but it isn't ideal.  You may find yourself
+   accidentally editting the Java code for creating an Account when your really want to be editting the code for creating a Payment.
+   
+   Tapestry is encouraging you to use a more descriptive name: <<<Create>>><Address> not just <<<Create>>>, but it isn't making you pay the cost (in terms of longer,
+   uglier URLs).  The URL will still be http://localhost:8080/tutorial1/address/create.
+   
+* Using the BeanEditForm component
+
+  Time to start putting together the logic for this form.  In fact, let's use a magic trick ... the BeanEditForm component.  This component can analyze a class and create an editor UI for it all in one go.
+  Let's give it a try.
+  
+  Add the following to the CreateAddress template (replacing the "coming soon ..." message):
+  
+---
+  <t:beaneditform object="address"/>
+---
+
+  And match that up with a property in the CreateAddress class:
+  
+----
+  private Address _address;
+
+  public Address getAddress()
+  {
+    return _address;
+  }
+
+  public void setAddress(Address address)
+  {
+    _address = address;
+  }
+----
+   
+   When you refresh the page, you'll see the following:
+   
+[address-v1.png] Initial version of the create address form
+
+  Tapestry's done quite a bit of work here.  It's created a form that includes a field for each property.  Further, it's seen that the
+  honorific property is an enumerated type, and presented that as a drop-down list.
+  
+  In addition, Tapestry has converted the property names ("city", "email", "firstName") to user presentable labels ("City", "Email", "First Name").
+  In fact, these are \<label\> elements, so clicking a label will move the cursor into the corresponding field.
+  
+  This is an awesome start; it's a presentable interface, quite nice in fact for a few  minute's work.  But it's far from perfect; let's get started
+  with some customizations.
+  
+* Changing field order
+
+  It looks like the fields are being displayed in alphabetical order, ("city" first, "zip" last).  That's not quite the reality, however:  If you check the listing
+  for the Address class, you'll see that the getter and setter methods are in alphabetical order (care of Eclipse, which generated all those methods from the fields).
+     
+  The BeanEditForm works in the order in which the <getter methods> are defined in the class.  Let's reorder them into a more reasonable order:
+  
+  * honorific
+  
+  * firstName
+  
+  * lastName
+  
+  * street1
+  
+  * street2
+  
+  * city
+  
+  * state
+  
+  * zip
+  
+  * email
+  
+  * phone
+  
+  []
+  
+  (This is also the order of in which the fields are defined.)
+  
+  Because Address is not a component class, it is necessary to restart Jetty to see the effects of these changes.
+  
+  Once Jetty is restarted, hit the browser's refresh button to see the fields in the correct order:
+  
+[address-v2.png] Create address form with fields in proper order
+
+
+   
+
+  
+  

Added: tapestry/tapestry5/trunk/tapestry-tutorial1/src/site/resources/address-v1.png
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-tutorial1/src/site/resources/address-v1.png?view=auto&rev=548539
==============================================================================
Binary file - no diff available.

Propchange: tapestry/tapestry5/trunk/tapestry-tutorial1/src/site/resources/address-v1.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tapestry/tapestry5/trunk/tapestry-tutorial1/src/site/resources/address-v2.png
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-tutorial1/src/site/resources/address-v2.png?view=auto&rev=548539
==============================================================================
Binary file - no diff available.

Propchange: tapestry/tapestry5/trunk/tapestry-tutorial1/src/site/resources/address-v2.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream