You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2005/09/06 15:45:06 UTC

svn commit: r278999 - in /jakarta/tapestry/trunk/src/documentation: content/xdocs/ content/xdocs/QuickStart/ resources/images/QuickStart/

Author: hlship
Date: Tue Sep  6 06:44:56 2005
New Revision: 278999

URL: http://svn.apache.org/viewcvs?rev=278999&view=rev
Log:
Start a QuickStart page describing how to create forms.

Added:
    jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/forms.xml
    jakarta/tapestry/trunk/src/documentation/resources/images/QuickStart/forms1.png   (with props)
    jakarta/tapestry/trunk/src/documentation/resources/images/QuickStart/forms2.png   (with props)
Modified:
    jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/directlink.xml
    jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/index.xml
    jakarta/tapestry/trunk/src/documentation/content/xdocs/links.ent
    jakarta/tapestry/trunk/src/documentation/content/xdocs/site.xml

Modified: jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/directlink.xml
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/directlink.xml?rev=278999&r1=278998&r2=278999&view=diff
==============================================================================
--- jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/directlink.xml (original)
+++ jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/directlink.xml Tue Sep  6 06:44:56 2005
@@ -502,10 +502,11 @@
 </section>  
 
 <section>
-  <title>Next: ???</title>
-  
+  <title>Next: <link href="forms.html">Forms</link></title>
+
 <p>
-  Don't know what's next ... haven't written it yet.  Probably start with Forms.
+&DirectLink; may be a real workhorse, but the heart of most web applications are the
+subject of our next tutorial: <link href="forms.html">Tapestry Forms</link>.
 </p>
 
 </section>

Added: jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/forms.xml
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/forms.xml?rev=278999&view=auto
==============================================================================
--- jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/forms.xml (added)
+++ jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/forms.xml Tue Sep  6 06:44:56 2005
@@ -0,0 +1,483 @@
+<?xml version="1.0"?>
+<!-- 
+   Copyright 2005 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.2//EN" "./dtd/document-v12.dtd"
+[
+	<!ENTITY projectroot '../'>
+	<!ENTITY % common.ent SYSTEM "common.ent">
+	<!ENTITY % links.ent SYSTEM "../links.ent">
+	%common.ent;
+	%links.ent;  
+]>
+<document>
+  <header>
+    <title>QuickStart: Forms</title>
+  </header>
+
+<body>
+
+<p>
+In this tutorial, we'll cover the basics of Tapestry forms, and gain an understanding of the lifecycle of
+a Tapestry application.  We'll also see how to transfer information from one
+page to another.
+</p>	
+
+<p>
+The theme of this tutorial is an application used to track third-party libraries for Tapestry.
+Each project will have a number of properties:
+</p>
+
+<ul>
+	<li>name</li>
+	<li>release ID</li>
+	<li>short and long description</li>
+	<li>category</li>
+	<li>supported Tapestry version</li>
+	<li>release date</li>
+	<li>public (visible to others) or private (visible only to the owner)</li>
+</ul>
+	
+<p>
+	Later tutorials will return to this theme, and cover the issues related to
+	accessing data from a database. For this tutorial, we're just going to collect
+	the above data (in an Add Project page), and then echo it back to the user.
+</p>	
+	
+<section>
+	<title>Home Page</title>
+	
+<p>
+The Home page for our application is very simple, it doesn't require a Java class:
+</p>	
+
+<source><![CDATA[
+<html jwcid="@Shell" title="Tapestry Component Database">
+<body>
+	
+<h1>Tapestry Component Database</h1>
+
+<p>
+  Options:
+</p>
+
+<ul>
+  <li><a jwcid="@PageLink" page="AddProject">Add New Project</a></li>
+</ul>
+	
+	
+</body>
+</html>
+]]></source>
+	
+<p>
+We've introduced another handy component, &Shell;.  This component is just a 
+convienience for generating the &lt;html&gt;, &lt;head&gt;, and &lt;title&gt; tags (though
+it has quite a few other tricks up its sleeve).
+</p>	
+	
+	
+</section>	
+
+<section>
+	<title>Value Object</title>
+	
+<p>
+	One of the cornerstones of Tapestry is the ability to edit properties of value objects directly.
+	These value objects, in a real application, will be read from the databsae, editted by Tapestry
+	components, then written back into the database.
+</p>
+
+<p>
+	Objects editted by Tapestry in this manner have <em>no</em> requirements.  Unlike pages, they don't
+	have to extend a base class or implement an interface. They are truly the <strong>Model</strong>
+	in the <strong>Model-View-Controller Pattern</strong>.
+</p>
+
+<p>
+	For this tutorial, we're using a very simple value object:
+</p>
+
+<source><![CDATA[package tutorial.forms.data;
+
+import java.util.Date;
+
+/**
+ * Contains the name and description of a release of a project.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public class ProjectRelease
+{
+    private String _name;
+
+    private String _releaseId;
+
+    private String _shortDescription;
+
+    private String _longDescription;
+
+    private String _category;
+
+    private String _tapestryVersion;
+
+    private Date _releaseDate;
+
+    private boolean _public;
+
+    /**
+     * A user-specified category, used to group similar projects.
+     */
+    public String getCategory()
+    {
+        return _category;
+    }
+
+    public void setCategory(String category)
+    {
+        _category = category;
+    }
+
+    /**
+     * A longer description used on a detail page.
+     */
+    public String getLongDescription()
+    {
+        return _longDescription;
+    }
+
+    public void setLongDescription(String longDescription)
+    {
+        _longDescription = longDescription;
+    }
+
+    /**
+     * The name of the project.
+     */
+    public String getName()
+    {
+        return _name;
+    }
+
+    public void setName(String name)
+    {
+        _name = name;
+    }
+
+    /**
+     * If true, the project is visible to other users. If false, then the project is not visible.
+     * This is used as a "draft" mode, when information about the project is not complete.
+     */
+    public boolean isPublic()
+    {
+        return _public;
+    }
+
+    public void setPublic(boolean public1)
+    {
+        _public = public1;
+    }
+
+    /**
+     * The date when the project was released. Used to generate a chronological listing.
+     */
+    public Date getReleaseDate()
+    {
+        return _releaseDate;
+    }
+
+    public void setReleaseDate(Date releaseDate)
+    {
+        _releaseDate = releaseDate;
+    }
+
+    /**
+     * The version number of the project that was released.
+     */
+    public String getReleaseId()
+    {
+        return _releaseId;
+    }
+
+    public void setReleaseId(String releaseId)
+    {
+        _releaseId = releaseId;
+    }
+
+    /**
+     * A single-line description used in an overview listing.
+     */
+    public String getShortDescription()
+    {
+        return _shortDescription;
+    }
+
+    public void setShortDescription(String shortDescription)
+    {
+        _shortDescription = shortDescription;
+    }
+
+    /**
+     * The version of Tapestry required for the project.
+     */
+    public String getTapestryVersion()
+    {
+        return _tapestryVersion;
+    }
+
+    public void setTapestryVersion(String tapestryVersion)
+    {
+        _tapestryVersion = tapestryVersion;
+    }
+}
+]]></source>
+
+</section>
+
+<section>
+	<title>AddProject Page</title>
+	
+<p>
+	As we've seen, the Home page includes a link to the AddProject page; the AddProject page
+	will contain the form that collects the data about the project before storing it into a database.
+	We don't have a database in this example, but we can still collect the data.
+</p>	
+	
+<section>
+	<title>HTML Template</title>
+	
+<source><![CDATA[<html jwcid="@Shell" title="Add New Project">
+  <body jwcid="@Body">
+    <h1>Add New Project</h1>
+    <form jwcid="form@Form" success="listener:doSubmit">
+      <table>
+        <tr>
+          <th>Name</th>
+          <td>
+            <input jwcid="name@TextField" value="ognl:project.name" size="40"/>
+          </td>
+        </tr>
+        <tr>
+          <th>Release ID</th>
+          <td>
+            <input jwcid="release@TextField" value="ognl:project.releaseId" size="20"/>
+          </td>
+        </tr>
+        <tr>
+          <th>Short Description</th>
+          <td>
+            <input jwcid="short@TextField" value="ognl:project.shortDescription"/>
+          </td>
+        </tr>
+        <tr>
+          <th>Long Description</th>
+          <td>
+            <textarea jwcid="long@TextArea" value="ognl:project.longDescription" rows="10" cols="40"/>
+          </td>
+        </tr>
+        <tr>
+          <th>Tapestry Version</th>
+          <td>
+            <input jwcid="tapestryVersion@TextField" value="ognl:project.tapestryVersion" size="20"/>
+          </td>
+        </tr>
+        <tr>
+          <th>Release Date</th>
+          <td>
+            <input jwcid="releaseDate@DatePicker" value="ognl:project.releaseDate"/>
+          </td>
+        </tr>
+        <tr>
+          <th>Public</th>
+          <td>
+            <input jwcid="public@Checkbox" value="ognl:project.public"/>
+          </td>
+        </tr>
+      </table>
+      <input type="submit" value="Add Project"/>
+    </form>
+  </body>
+</html>]]></source>	
+	
+<p>
+This template introduces a number of new components:
+</p>  
+
+<ul>
+  <li>&Body; -- organizes the JavaScript generated for the page (needed to use the &DatePicker;)</li>
+  <li>&Form; -- generates an HTML form and controls the submit behavior</li>
+  <li>&TextField; -- creates a text field (&lt;input type="text"/&gt;) used to <em>edit</em> (read and update) a property
+    of the page</li>
+  <li>&TextArea; -- as with &TextField;, but generates a multi-line &lt;textarea&gt;</li>
+  <li>&DatePicker; -- a JavaScript popup calendar</li>
+  <li>&Checkbox;-- edits a <em>boolean</em> property of the page</li> 
+</ul>
+
+<p>
+The &Form;'s success parameter is linked to a listener method. It is invoked only when there
+are no validation errors. We'll discuss validation in a later tutorial.
+</p>
+
+<p>
+ The &Body; component plays a crucial role in Tapestry; it organizes all the JavaScript generated when
+ a page renders. It assists components with generated unique names for client-side variables and functions,
+ and organizes all the JavaScript generated by all the component within the page into two large blocks (one at
+ the top of the page, one at the bottom). The &DatePicker; component will not operate unless it is
+ enclosed by a &Body; component.
+</p>
+  
+<p>
+The &TextField; and &TextArea; components edit properties of the page.  Because the value
+parameter is an &OGNL; expression, it is not limited to editting properties directly exposed
+by the page class; it can follow property paths. We'll see how to define the project
+property of the page shortly.
+</p>
+
+<p>
+  As you can see, Tapestry offers a number of components for editting specific types of properties. In addition,
+  we'll see in a bit how the existing components can be configured for editting other types as well.
+</p>
+
+<p>
+  As the template shows, this page is reliant on 
+  having a specific Java class, with a doSubmit() listener method and a project property. Let's create that next.
+</p>
+
+</section>
+
+<section>
+  <title>AddProject Page Class</title>
+  
+<p>
+  Let's start with the minimum for this class and add details as necessary.
+</p>  
+
+<source><![CDATA[package tutorial.forms.pages;
+
+import org.apache.tapestry.html.BasePage;
+
+import tutorial.forms.data.ProjectRelease;
+
+/**
+ * Java class for the AddProject page; contains a form used to collect data for creating a new
+ * {@link tutorial.forms.data.ProjectRelease}.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public abstract class AddProject extends BasePage
+{
+    public abstract ProjectRelease getProject();
+
+    public void doSubmit()
+    {
+
+    }
+}
+]]></source>
+  
+<p>
+  Maybe this is too minimal; if we launch the application and choose the Add New Project link, we
+  get an exception:
+</p>  
+
+<figure src="&images-url;/forms1.png" alt="Null Pointer Exception"/>
+  
+<p>
+  The root of this exception is a null value:  we defined a place to store a ProjectRelease object
+  but didn't actually provide an instance.  &OGNL; attempted to dereference through the null value
+  and threw the OgnlException. Here we can see the advantage of Tapestry's exception reporting ... showing the 
+  stack of exceptions gave us context into our application (the line in the template associated with the
+  error) without obscuring the underlying cause.
+</p>  
+
+<p>
+  What we need to do is create an instance of ProjectRelease and store it into
+  the property so that the &TextField; components can edit it.  We have to be careful
+  because in a live application, pages will be pooled and reused constantly. The best approach in Tapestry is to
+  listen to a <em>page lifecycle event</em> and create the ProjectRelease object just as needed.
+</p>
+
+<p>
+  For this situation, the right approach is to listen for the PageBeginRender event, and
+  store the new instance into the property then.  The ProjectRelease object will be used for the
+  duration of the request, then discarded ata the end of the request.
+</p>
+
+<p>
+  Listening for these lifecycle events is simple; you just need to select the correct listener interface
+  and implement it; Tapestry will automatically register your page to receive the notifications.  Here,
+  the interface is &PageBeginRenderListener;:
+</p>
+
+<source><![CDATA[package tutorial.forms.pages;
+
+import java.util.Date;
+
+import org.apache.tapestry.event.PageBeginRenderListener;
+import org.apache.tapestry.event.PageEvent;
+import org.apache.tapestry.html.BasePage;
+
+import tutorial.forms.data.ProjectRelease;
+
+/**
+ * Java class for the AddProject page; contains a form used to collect data for creating a new
+ * {@link tutorial.forms.data.ProjectRelease}.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public abstract class AddProject extends BasePage implements PageBeginRenderListener
+{
+    public abstract ProjectRelease getProject();
+
+    public abstract void setProject(ProjectRelease project);
+
+    public void pageBeginRender(PageEvent event)
+    {
+        ProjectRelease project = new ProjectRelease();
+
+        project.setReleaseDate(new Date());
+
+        setProject(project);
+    }
+
+    public void doSubmit()
+    {
+
+    }
+}
+]]></source>
+  
+<p>
+  The pageBeginRender() method will be invoked whenever the page renders. It is also, due to a useful quirk of Tapestry,
+  invoked when a form within the page is submitted. Not only can we create an instance, but we
+  have the opportunity to set some initial values for fields.
+</p>  
+  
+<p>
+  With this in place, the page will now render:
+</p>  
+
+<figure src="&images-url;/forms2.png" alt="AddProject Page"/>
+  
+  
+</section>
+	
+</section>
+
+<em>More coming soon ...</em>
+
+</body>
+</document>
\ No newline at end of file

Modified: jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/index.xml
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/index.xml?rev=278999&r1=278998&r2=278999&view=diff
==============================================================================
--- jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/index.xml (original)
+++ jakarta/tapestry/trunk/src/documentation/content/xdocs/QuickStart/index.xml Tue Sep  6 06:44:56 2005
@@ -50,7 +50,7 @@
 </p>
   
 <p>
-The source code for the all the tutorials are distributed inside a single tarbar: tapestry-tutorials.tar.gz, available
+The source code for the all the tutorials are distributed inside a single tarball: tapestry-tutorials.tar.gz, available
 from <link href="&quickstart-download-url;">&quickstart-download-url;</link>.
 </p>  
     

Modified: jakarta/tapestry/trunk/src/documentation/content/xdocs/links.ent
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/src/documentation/content/xdocs/links.ent?rev=278999&r1=278998&r2=278999&view=diff
==============================================================================
--- jakarta/tapestry/trunk/src/documentation/content/xdocs/links.ent (original)
+++ jakarta/tapestry/trunk/src/documentation/content/xdocs/links.ent Tue Sep  6 06:44:56 2005
@@ -128,6 +128,7 @@
 <!ENTITY Body 				'<link href="site:Body">Body</link>'>
 <!ENTITY Checkbox 			'<link href="site:Checkbox">Checkbox</link>'>
 <!ENTITY Conditional 		'<link href="site:Conditional">Conditional</link>'>
+<!ENTITY DatePicker			'<link href="site:DatePicker">DatePicker</link>'>
 <!ENTITY Delegator 			'<link href="site:Delegator">Delegator</link>'>
 <!ENTITY Describe			'<link href="site:Describe">Describe</link>'>
 <!ENTITY DirectLink 		'<link href="site:DirectLink">DirectLink</link>'>

Modified: jakarta/tapestry/trunk/src/documentation/content/xdocs/site.xml
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/src/documentation/content/xdocs/site.xml?rev=278999&r1=278998&r2=278999&view=diff
==============================================================================
--- jakarta/tapestry/trunk/src/documentation/content/xdocs/site.xml (original)
+++ jakarta/tapestry/trunk/src/documentation/content/xdocs/site.xml Tue Sep  6 06:44:56 2005
@@ -46,6 +46,7 @@
       <qsintro label="Introduction" href="index.html"/>
       <helloworld label="Hello World" href="helloworld.html"/>
       <directlink label="DirectLink" href="directlink.html"/>
+	  <forms label="Forms" href="forms.html"/>
     </QuickStart>
     
     <UsersGuide label="Users Guide" tab="users-guide" href="UsersGuide/">

Added: jakarta/tapestry/trunk/src/documentation/resources/images/QuickStart/forms1.png
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/src/documentation/resources/images/QuickStart/forms1.png?rev=278999&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jakarta/tapestry/trunk/src/documentation/resources/images/QuickStart/forms1.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: jakarta/tapestry/trunk/src/documentation/resources/images/QuickStart/forms2.png
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/src/documentation/resources/images/QuickStart/forms2.png?rev=278999&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jakarta/tapestry/trunk/src/documentation/resources/images/QuickStart/forms2.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org