<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" | |
"http://www.w3.org/TR/html4/loose.dtd"> | |
<!-- | |
Licensed to the Apache Software Foundation (ASF) under one | |
or more contributor license agreements. See the NOTICE file | |
distributed with this work for additional information | |
regarding copyright ownership. The ASF licenses this file | |
to you 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. | |
--> | |
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> | |
<meta name="Author" content="Malcolm Edgar"/> | |
<meta name="description" lang="en" content="Apache Click Java web application framework"/> | |
<meta name="keywords" lang="en" content="Apache Click, Click Framework, Java, JEE, J2EE, web application framework, open source"/> | |
<title>Apache Click</title> | |
<link rel="stylesheet" type="text/css" href="../help.css"/> | |
<link rel="stylesheet" type="text/css" href="table.css"/> | |
<style type="text/css"> | |
li { | |
margin-bottom: 0.75em; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Introduction</h1> | |
Click is a simple JEE web application framework for commercial Java developers. | |
<p> | |
Click is an open source project, licensed under the | |
<a href="LICENSE.txt">Apache</a> license. | |
<p> | |
Click uses an event based programming model for processing Servlet requests and | |
<a target='topic' href='velocity/velocity.html'>Velocity</a> for rendering | |
the response. (Note other template engines such as <a target="_blank" href="http://java.sun.com/products/jsp/">JSP</a> | |
and <a target="_blank" href="http://freemarker.sourceforge.net/">Freemarker</a> are also supported) | |
<p> | |
This framework uses a single servlet, called | |
<a target="topic" href="click-api/org/apache/click/ClickServlet.html">ClickServlet</a>, to | |
act as a request dispatcher. When a request arrives ClickServlet creates a | |
<a target="topic" href="click-api/org/apache/click/Page.html">Page</a> object to | |
process the request and then uses the page's Velocity template to render the | |
results. | |
<p> | |
Pages provide a simple thread safe programming environment, with a new | |
page instance created for each servlet request. | |
<p> | |
Possibly the best way to see how Click works is to dive right in and look at some | |
examples: | |
<ol> | |
<li><a href="#hello-world">Hello World</a> - the Hello World classic | |
</li> | |
<li><a href="#control-listener">Control Listener</a> - a ActionLink control listener example | |
</li> | |
<li><a href="#simple-table">Simple Table</a> - a simple Table control example | |
</li> | |
<li><a href="#advanced-table">Advanced Table</a> - a more advanced Table example | |
</li> | |
<li><a href="#simple-form">Simple Form</a> - a simple Form example | |
</li> | |
<li><a href="#advanced-form">Advanced Form</a> - a more advanced Form example | |
</li> | |
</ol> | |
These examples are available online at <a class="external" target="_blank" href="http://www.avoka.com/click-examples/">http://www.avoka.com/click-examples/</a> | |
under the menu "Intro Examples". | |
<p> </p> | |
<a name="hello-world" class="heading"></a><h2>1. Hello World Example</h2> | |
A Hello World example in Click would look something like this. | |
<p/> | |
First we create a <tt>HelloWorld</tt> page class: | |
<pre class="codeJava"> | |
<span class="kw">package</span> <span class="red">examples.page</span>; | |
<span class="kw">import</span> java.util.Date; | |
<span class="kw">import</span> org.apache.click.Page; | |
<span class="kw">public</span> HelloWorld <span class="kw">extends</span> Page { | |
<span class="kw">public</span> Date <span class="st">time</span> = <span class="kw">new</span> Date(); | |
} | |
</pre> | |
Next we have a page template <span class="blue">hello-world.htm</span>: | |
<pre class="codeHtml"> | |
<html> | |
<body> | |
<h2>Hello World</h2> | |
Hello world from Click at <span class="st">$time</span> | |
</body> | |
</html> | |
</pre> | |
Click is smart enough to figure out that the <tt>HelloWorld</tt> page class maps | |
to the template <span class="blue">hello-world.htm</span>. We only have to inform | |
Click of the <tt>package</tt> of the HelloWorld class, in this case <tt>examples.page</tt>. | |
<p/> | |
We do that through the | |
<a target='topic' href="configuration.html#application-configuration">click.xml</a> | |
configuration file which tells Click to map <span class="blue">hello-world.htm</span> | |
requests to our <tt>examples.page.HelloWorld</tt> page class. | |
<pre class="codeConfig"> | |
<click-app> | |
<pages package="<span class="red">examples.page</span>"/> | |
</click-app> | |
</pre> | |
<p/> | |
At runtime the ClickSerlvet maps a GET <span class="blue">hello-world.htm</span> | |
request to our page class <tt>example.page.HelloWorld</tt> and creates a new instance. | |
The HelloWorld page creates a new public <tt>Date</tt> object, which is automatically | |
added to the pages model using the fields name <span class="st">time</span>. | |
<p/> | |
The page model is then merged with the template which substitutes the | |
<span class="st">$time</span> parameter with the <tt>Date</tt> object. | |
Velocity then renders the merged template which looks something like | |
<table class="htmlExample" cellspacing="12"> | |
<tr> | |
<td> | |
<h2 style="margin-top: 0em;">Hello World</h2> | |
Hello world from Click at Tue May 08 19:37:05 EST 2007 | |
</td> | |
</tr> | |
</table> | |
<p> </p> | |
<a name="control-listener" class="heading"></a><h2>2. Control Listener Example</h2> | |
Click includes a library of <a target="topic" href="controls.html">Controls</a> which | |
provide user interface functionality. | |
<p/> | |
One of the commonly used controls is the | |
<a target="topic" href="click-api/org/apache/click/control/ActionLink.html">ActionLink</a>, | |
which you can use to have a HTML link call a method on a Page object. For example: | |
<pre class="codeJava"> | |
<span class="kw">public class</span> ControlListenerPage <span class="kw">extends</span> Page { | |
<span class="kw">public</span> ActionLink myLink = <span class="kw">new</span> ActionLink(); | |
<span class="kw">public</span> String msg; | |
<span class="cm">// ----------------------------------------------------------- Constructors | |
/** | |
* Create a new Page instance. | |
*/</span> | |
<span class="kw">public</span> ControlListenerPage() { | |
myLink.setListener(<span class="kw">this</span>, <span class="st">"onMyLinkClick"</span>); | |
} | |
<span class="cm">// --------------------------------------------------------- Event Handlers</span> | |
<span class="cm">/** | |
* Handle the myLink control click event. | |
*/</span> | |
<span class="kw">public boolean</span> onMyLinkClick() { | |
msg = <span class="st">"ControlListenerPage#"</span> + hashCode() | |
+ <span class="st">" object method <tt>onMyLinkClick()</tt> invoked."</span>; | |
<span class="kw">return true</span>; | |
} | |
} </pre> | |
In the Page class we create an ActionLink called <span class="blue">myLink</span> | |
and define the control's listener to be the page method <tt>onMyLinkClick()</tt>. | |
When a user clicks on <span class="blue">myLink</span> control it will invoke the | |
listener method <tt>onMyLinkClick()</tt>. | |
<p/> | |
In Click a control listener method can have any name but it must return a boolean value. | |
The boolean return value specifies whether processing of page events should continue. | |
This control listener pattern provides a short hand way for wiring up action listener methods | |
without having to define anonymous inner classes. | |
<p/> | |
Back to our example, in the page template we define a HTML link and have the | |
<span class="blue">myLink</span> control render the link's href attribute: | |
<pre class="codeHtml"> | |
<html> | |
<head> | |
<link type="text/css" rel="stylesheet" href="style.css"></link> | |
</head> | |
<body> | |
Click myLink control <a href="<span class="blue">$myLink.href</span>">here</a>. | |
<span class="red">#if</span> (<span class="blue">$msg</span>) | |
<div id="msgDiv"> <span class="blue">$msg</span> </div> | |
<span class="red">#end</span> | |
</body> | |
</html> | |
</pre> | |
At runtime this page would be rendered as: | |
<table class="htmlExample" cellspacing="12"> | |
<tr> | |
<td> | |
Click myLink control <a href="/click-examples/introduction/control-listener.htm?actionLink=myLink">here</a>. | |
</td> | |
</tr> | |
</table> | |
When a user clicks on the link the <tt>onMyLinkClick()</tt> method is invoked. This | |
method then creates <span class="blue">msg</span> model value, which is rendered in the page as: | |
<table class="htmlExample" cellspacing="12"> | |
<tr> | |
<td> | |
Click myLink control <a href="/click-examples/introduction/control-listener.htm?actionLink=myLink">here</a>. | |
<div class="msgDiv"> ControlListenerPage#12767107 object method <tt>onMyLinkClick()</tt> invoked. </div> | |
</td> | |
</tr> | |
</table> | |
<p> </p> | |
<a name="simple-table" class="heading"></a><h2>3. Simple Table Example</h2> | |
One of the most useful Click controls is the | |
<a target="topic" href="click-api/org/apache/click/control/Table.html">Table</a> | |
control. | |
<p/> | |
An example usage of the Table control in a customers Page is provided below: | |
<pre class="codeJava"> | |
<span class="kw">public class</span> SimpleTablePage <span class="kw">extends</span> Page { | |
<span class="kw">public</span> Table <span class="st">table</span> = <span class="kw">new</span> Table(); | |
<span class="cm">// ------------------------------------------------------------ Constructor</span> | |
<span class="kw">public</span> SimpleTablePage() { | |
table.setClass(Table.CLASS_ITS); | |
table.addColumn(<span class="kw">new</span> Column(<span class="st">"id"</span>)); | |
table.addColumn(<span class="kw">new</span> Column(<span class="st">"name"</span>)); | |
table.addColumn(<span class="kw">new</span> Column(<span class="st">"email"</span>)); | |
table.addColumn(<span class="kw">new</span> Column(<span class="st">"investments"</span>)); | |
} | |
<span class="cm">// --------------------------------------------------------- Event Handlers</span> | |
<span class="cm">/** | |
* @see Page#onRender() | |
*/</span> | |
<span class="kw">public void</span> onRender() { | |
List list = getCustomerService().getCustomersSortedByName(10); | |
table.setRowList(list); | |
} | |
} </pre> | |
In this Page code example a Table control is declared, we set the table's HTML class, | |
and then define a number of table <a target="topic" href="click-api/org/apache/click/control/Column.html">Column</a> | |
objects. In the column definitions we specify the name of the column in the constructor, | |
which is used for the table column header and also to specify the row object property | |
to render. | |
<p/> | |
The last thing we need to do is populate the table with data. To do this we override the | |
Page <tt>onRender()</tt> method and set the table row list before it is rendered. | |
<p/> | |
In our Page template we simply reference the <span class="blue">$table</span> object | |
which is rendered when its <tt>toString()</tt> method is called. | |
<pre class="codeHtml"> | |
<html> | |
<head> | |
<span class="blue">$cssImports</span> | |
</head> | |
<body> | |
<span class="blue">$table</span> | |
</body> | |
</html> | |
<span class="blue">$jsImports</span> | |
</pre> | |
Note above we also specify the <span class="blue">$cssImports</span> reference so the table can include any | |
CSS imports or styles in the header, and the <span class="blue">$jsImports</span> reference | |
any JavaScript imports or scripts at the bottom. | |
<p/> | |
At runtime the Table would be rendered in the page as: | |
<table class="htmlExample" cellspacing="12"> | |
<tr> | |
<td> | |
<img src="../images/simple-table.png" border="0"/> | |
</td> | |
</tr> | |
</table> | |
<p> </p> | |
<a name="advanced-table" class="heading"></a><h2>4. Advanced Table Example</h2> | |
The Table control also provides support for: | |
<ul> | |
<li>automatic rendering</li> | |
<li>column formatting and custom rendering</li> | |
<li>automatic pagination</li> | |
<li>link control support</li> | |
</ul> | |
A more advanced Table example is provided below: | |
<pre class="codeJava"> | |
<span class="kw">public class</span> CustomerPage <span class="kw">extends</span> Page { | |
<span class="kw">public</span> Table <span class="st">table</span> = <span class="kw">new</span> Table(); | |
<span class="kw">public</span> PageLink editLink = <span class="kw">new</span> PageLink(<span class="st">"Edit"</span>, EditCustomer.<span class="kw">class</span>); | |
<span class="kw">public</span> ActionLink deleteLink = <span class="kw">new</span> ActionLink(<span class="st">"Delete"</span>, <span class="kw">this</span>, <span class="st">"onDeleteClick"</span>); | |
<span class="cm">// ------------------------------------- Constructor</span> | |
<span class="kw">public</span> CustomersPage() { | |
table.setClass(Table.<span class="st">CLASS_ITS</span>); | |
table.setPageSize(10); | |
table.setShowBanner(<span class="kw">true</span>); | |
table.setSortable(<span class="kw">true</span>); | |
table.addColumn(<span class="kw">new</span> Column(<span class="st">"id"</span>)); | |
table.addColumn(<span class="kw">new</span> Column(<span class="st">"name"</span>)); | |
Column column = <span class="kw">new</span> Column(<span class="st">"email"</span>); | |
column.setAutolink(<span class="kw">true</span>); | |
column.setTitleProperty(<span class="st">"name"</span>); | |
table.addColumn(column); | |
table.addColumn(<span class="kw">new</span> Column(<span class="st">"investments"</span>)); | |
editLink.setImageSrc(<span class="st">"/images/table-edit.png"</span>); | |
editLink.setTitle(<span class="st">"Edit customer details"</span>); | |
editLink.setParameter(<span class="st">"referrer"</span>, <span class="st">"/introduction/advanced-table.htm"</span>); | |
deleteLink.setImageSrc(<span class="st">"/images/table-delete.png"</span>); | |
deleteLink.setTitle(<span class="st">"Delete customer record"</span>); | |
deleteLink.setAttribute(<span class="st">"onclick"</span>, <span class="st">"return window.confirm('Are you sure you want to delete this record?');"</span>); | |
column = <span class="kw">new</span> Column(<span class="st">"Action"</span>); | |
column.setTextAlign(<span class="st">"center"</span>); | |
AbstractLink[] links = <span class="kw">new</span> AbstractLink[] { editLink, deleteLink }; | |
column.setDecorator(<span class="kw">new</span> LinkDecorator(table, links, <span class="st">"id"</span>)); | |
column.setSortable(<span class="kw">false</span>); | |
table.addColumn(column); | |
} | |
<span class="cm">// ---------------------------------- Event Handlers</span> | |
<span class="cm">/** | |
* Handle the delete row click event. | |
*/</span> | |
<span class="kw">public boolean</span> onDeleteClick() { | |
Integer id = deleteLink.getValueInteger(); | |
getCustomerService().deleteCustomer(id); | |
<span class="kw">return true</span>; | |
} | |
<span class="cm">/** | |
* @see Page#onRender() | |
*/</span> | |
<span class="kw">public void</span> onRender() { | |
List list = getCustomerService().getCustomersByName(); | |
table.setRowList(list); | |
} | |
} </pre> | |
In this Page code example a Table control is declared and a number of | |
<a target="topic" href="click-api/org/apache/click/control/Column.html">Column</a> | |
objects are added. A deleteLink | |
<a target="topic" href="click-api/org/apache/click/control/ActionLink.html">ActionLink</a> | |
control is used as a decorator for the "Action" column. This control will invoke the | |
Page <tt>onDeleteClick()</tt> method when it is clicked. Finally we have the | |
Page <tt>onRender()</tt> method which is used to populate the Table control with | |
rows before it is rendered. | |
<p/> | |
In our Page template we simply reference the <span class="blue">$table</span> object | |
which is rendered when its <tt>toString()</tt> method is called. | |
<pre class="codeHtml"> | |
<html> | |
<head> | |
<span class="blue">$cssImports</span> | |
</head> | |
<body> | |
<span class="blue">$table</span> | |
</body> | |
</html> | |
<span class="blue">$jsImports</span> | |
</pre> | |
At runtime the Table would be rendered in the page as: | |
<table class="htmlExample" cellspacing="12"> | |
<tr> | |
<td> | |
<img src="../images/advanced-table.png" border="0"/> | |
</td> | |
</tr> | |
</table> | |
In this example if a user click on the Delete link the <tt>onDeleteClick()</tt> | |
method will be called on the Page deleting the customer record. | |
<p> </p> | |
<a name="simple-form" class="heading"></a><h2>5. Simple Form Example</h2> | |
The <a target="topic" href="click-api/org/apache/click/control/Form.html">Form</a> and | |
<a target="topic" href="click-api/org/apache/click/control/Field.html">Field</a> controls | |
are also some of the most commonly used controls in the Click Framework. | |
<p/> | |
The SimpleForm page below provides a demonstration of using these controls. | |
<p/> | |
In our example code we have the page's constructor adding a | |
<a target="topic" href="click-api/org/apache/click/control/TextField.html">TextField</a> field and a | |
<a target="topic" href="click-api/org/apache/click/control/Submit.html">Submit</a> button to the form. | |
A page method is also set as a control listener on the form. | |
Also note in this example the page's public <span class="st">form</span> field is | |
automatically added to its list of controls. | |
<pre class="codeJava"> | |
<span class="kw">public class</span> SimpleForm <span class="kw">extends</span> Page { | |
<span class="kw">public</span> Form <span class="st">form</span> = <span class="kw">new</span> Form(); | |
<span class="kw">public</span> String msg; | |
<span class="cm">// ------------------------------------------------------------ Constructor</span> | |
<span class="kw">public</span> SimpleForm() { | |
form.add(<span class="kw">new</span> TextField(<span class="st">"name"</span>, <span class="kw">true</span>)); | |
form.add(<span class="kw">new</span> Submit(<span class="st">"OK"</span>)); | |
form.setListener(<span class="kw">this</span>, <span class="st">"onSubmit"</span>); | |
} | |
<span class="cm">// --------------------------------------------------------- Event Handlers</span> | |
<span class="cm">/** | |
* Handle the form submit event. | |
*/</span> | |
<span class="kw">public boolean</span> onSubmit() { | |
<span class="kw">if</span> (form.isValid()) { | |
msg = <span class="st">"Your name is "</span> + form.getFieldValue(<span class="st">"name"</span>); | |
} | |
<span class="kw">return true</span>; | |
} | |
} | |
</pre> | |
<p/> | |
Next we have the SimpleForm template <span class="blue">simple-form.htm</span>. The | |
Click application automatically associates the <tt>simple-form.htm</tt> template with | |
the <tt>SimpleForm</tt> class. | |
<pre class="codeHtml"> | |
<html> | |
<head> | |
<span class="blue">$cssImports</span> | |
</head> | |
<body> | |
<span class="blue">$form</span> | |
<span class="red">#if</span> (<span class="blue">$msg</span>) | |
<div id="msgDiv"> <span class="blue">$msg</span> </div> | |
<span class="red">#end</span> | |
</body> | |
</html> | |
<span class="blue">$jsImports</span> | |
</pre> | |
When the SimpleForm page is first requested the <span class="blue">$form</span> object will | |
automatically render itself as: | |
<table class="htmlExample" cellspacing="12"> | |
<tr> | |
<td> | |
<form method="post" name="form" id="form" action="/click-examples/introduction/simple-form.htm"> | |
<input type="hidden" name="form_name" id="form_form_name" value="form"/> | |
<table class="form" id="form-form"> | |
<tr><td> | |
<table class="fields" id="form-fields"> | |
<tr class="fields"> | |
<td class="fields" align="left"><label for="form_name">Name</label><span class="required">*</span></td> | |
<td align="left"><input type="text" name="name" id="form_name" value="" size="20"/></td> | |
</tr> | |
</table> | |
</td></tr> | |
<tr><td align="left"> | |
<table class="buttons" id="form-buttons"> | |
<tr class="buttons"><td class="buttons"><input type="submit" name="OK" id="form_OK" value="OK"/></td></tr> | |
</table> | |
</td></tr> | |
</table> | |
</form> | |
</td> | |
</tr> | |
</table> | |
Say the user does not enter their name and presses the OK button to submit the form. | |
The ClickServlet creates a new SimpleForm page and processes the form control. | |
<p/> | |
The form control processes its fields and determines that it is invalid. The form | |
then invokes the listener method <tt>onSubmit()</tt>. As the form is not | |
valid this method simply returns true and the form renders the field validation errors. | |
<table class="htmlExample" cellspacing="12"> | |
<tr> | |
<td> | |
<form method="post" name="form" id="form" action="/click-examples/introduction/simple-form.htm"> | |
<input type="hidden" name="form_name" id="form_form_name" value="form"/> | |
<table class="form" id="form-form"> | |
<tr><td align="left"> | |
<table class="errors" id="form-errors"> | |
<tr class="errors"><td class="errors" align="left" colspan="2"><a class="error" href="#">You must enter a value for Name</a></td></tr> | |
</table> | |
</td></tr> | |
<tr><td> | |
<table class="fields" id="form-fields"> | |
<tr class="fields"> | |
<td class="fields" align="left"><label for="form_name" class="error">Name</label><span class="required">*</span></td> | |
<td align="left"><input type="text" name="name" id="form_name" value="" size="20" class="error"/></td> | |
</tr> | |
</table> | |
</td></tr> | |
<tr><td align="left"> | |
<table class="buttons" id="form-buttons"> | |
<tr class="buttons"><td class="buttons"><input type="submit" name="OK" id="form_OK" value="OK"/></td></tr> | |
</table> | |
</td></tr> | |
</table> | |
</form> | |
</td> | |
</tr> | |
</table> | |
Note the form will automatically maintain the entered state during the | |
post and validate cycle. | |
<p/> | |
Now if the user enters their name and clicks the OK button, the form will be | |
valid and the <tt>onSubmit()</tt> add a <span class="blue">msg</span> to the Pages | |
model. This will be rendered as: | |
<table class="htmlExample" cellspacing="12"> | |
<tr> | |
<td> | |
<form method="post" name="form" id="form" action="/click-examples/introduction/simple-form.htm"> | |
<input type="hidden" name="form_name" id="form_form_name" value="form"/> | |
<table class="form" id="form-form"> | |
<tr><td> | |
<table class="fields" id="form-fields"> | |
<tr class="fields"> | |
<td class="fields" align="left"><label for="form_name">Name</label><span class="required">*</span></td> | |
<td align="left"><input type="text" name="name" id="form_name" value="John Masters" size="20"/></td> | |
</tr> | |
</table> | |
</td></tr> | |
<tr><td align="left"> | |
<table class="buttons" id="form-buttons"> | |
<tr class="buttons"><td class="buttons"><input type="submit" name="OK" id="form_OK" value="OK"/></td></tr> | |
</table> | |
</td></tr> | |
</table> | |
</form> | |
<div class="msgDiv"> Your name is John Masters </div> | |
</td> | |
</tr> | |
</table> | |
<p> </p> | |
<a name="advanced-form" class="heading"></a><h2>6. Advanced Form Example</h2> | |
The <tt>AdvancedForm</tt> page below provides a more advanced demonstration | |
of using Form, Field and FielsSet controls. | |
<p/> | |
First we have an <tt>AdvancedForm</tt> class which setups up a | |
<a href="click-api/org/apache/click/control/Form.html">Form</a> | |
in its constructor. | |
The form's investment | |
<a href="click-api/org/apache/click/control/Select.html">Select</a> list is populated | |
in the page's <tt>onInit()</tt> method. At this point any page dependencies such | |
as the CustomerService should be available. | |
<p/> | |
Note in this example the page's public <span class="st">form</span> field is | |
automatically added to its list of controls. The <span class="st">msg</span> field | |
is added to the page's model. | |
<pre class="codeJava"> | |
<span class="kw">public class</span> AdvancedForm <span class="kw">extends</span> Page { | |
<span class="kw">public</span> Form form = <span class="kw">new</span> Form(); | |
<span class="kw">public</span> String msg; | |
<span class="kw">private</span> Select investmentSelect = <span class="kw">new</span> Select(<span class="st">"investment"</span>); | |
<span class="cm">// ------------------------------------------------------------ Constructor</span> | |
<span class="kw">public</span> AdvancedForm() { | |
FieldSet fieldSet = <span class="kw">new</span> FieldSet(<span class="st">"Customer"</span>); | |
form.add(fieldSet); | |
TextField nameField = <span class="kw">new</span> TextField(<span class="st">"name"</span>, <span class="kw">true</span>); | |
nameField.setMinLength(5); | |
nameField.setFocus(true); | |
fieldSet.add(nameField); | |
fieldSet.add(<span class="kw">new</span> EmailField(<span class="st">"email"</span>, <span class="kw">true</span>)); | |
fieldSet.add(investmentSelect); | |
fieldSet.add(<span class="kw">new</span> DateField(<span class="st">"dateJoined"</span>, <span class="kw">true</span>)); | |
fieldSet.add(<span class="kw">new</span> Checkbox(<span class="st">"active"</span>)); | |
form.add(<span class="kw">new</span> Submit(<span class="st">"ok"</span>, <span class="st">" OK "</span>, <span class="kw">this</span>, <span class="kw">"onOkClicked"</span>)); | |
form.add(<span class="kw">new</span> Submit(<span class="st">"cancel"</span>, <span class="kw">this</span>, <span class="st">"onCancelClicked"</span>)); | |
} | |
<span class="cm">// --------------------------------------------------------- Event Handlers | |
/** | |
* @see Page#onInit() | |
*/</span> | |
<span class="kw">public void</span> onInit() { | |
CustomerService customerService = getCustomerService(); | |
investmentSelect.add(Option.EMPTY_OPTION); | |
investmentSelect.addAll(customerService.getInvestmentCatetories()); | |
} | |
<span class="cm">/** | |
* Handle the OK button click event. | |
* | |
* @return true | |
*/</span> | |
<span class="kw">public boolean</span> onOkClicked() { | |
<span class="kw">if</span> (form.isValid()) { | |
Customer customer = <span class="kw">new</span> Customer(); | |
form.copyTo(customer); | |
getCustomerService().saveCustomer(customer); | |
form.clearValues(); | |
msg = <span class="st">"A new customer record has been created."</span>; | |
} | |
<span class="kw">return true</span>; | |
} | |
<span class="cm">/** | |
* Handle the Cancel button click event. | |
* | |
* @return false | |
*/</span> | |
<span class="kw">public boolean</span> onCancelClicked() { | |
setRedirect(HomePage.<span class="kw">class</span>); | |
<span class="kw">return false</span>; | |
} | |
} | |
</pre> | |
Next we have the AdvancedForm template <span class="blue">advanced-form.htm</span>. The | |
Click application automatically associates the <tt>advanced-form.htm</tt> template with | |
the <tt>AdvancedForm</tt> class. | |
<pre class="codeHtml"> | |
<html> | |
<head> | |
<span class="blue">$cssImports</span> | |
</head> | |
<body> | |
<span class="red">#if</span> (<span class="blue">$msg</span>) | |
<div id="msgDiv"> <span class="blue">$msg</span> </div> | |
<span class="red">#end</span> | |
<span class="blue">$form</span> | |
</body> | |
</html> | |
<span class="blue">$jsImports</span> | |
</pre> | |
When the AdvancedForm page is first requested the <span class="blue">$form</span> object will | |
automatically render itself as: | |
<table class="htmlExample" cellspacing="12"> | |
<tr> | |
<td> | |
<form method="post" name="form" id="form" action="/click-examples/introduction/advanced-form.htm"> | |
<input type="hidden" name="form_name" id="form_form_name" value="form"/> | |
<table class="form" id="form-form"> | |
<tr><td> | |
<table class="fields" id="form-fields"> | |
<tr class="fields"> | |
<td class="fields" colspan="2"> | |
<fieldset id="form_Customer"> | |
<legend id="form_Customer-legend">Customer</legend> | |
<table class="fields" id="form_Customer-fields"> | |
<tr class="fields"> | |
<td class="fields" align="left"><label for="form_name">Name</label><span class="required">*</span></td> | |
<td align="left"><input type="text" name="name" id="form_name" value="" size="20"/></td> | |
</tr> | |
<tr class="fields"> | |
<td class="fields" align="left"><label for="form_email">Email</label><span class="required">*</span></td> | |
<td align="left"><input type="text" name="email" id="form_email" value="" size="30"/></td> | |
</tr> | |
<tr class="fields"> | |
<td class="fields" align="left"><label for="form_investment">Investment</label> </td> | |
<td align="left"><select name="investment" id="form_investment" size="1"><option selected="selected" value=""></option><option value="Bonds">Bonds</option><option value="Commerical Property">Commerical Property</option><option value="Options">Options</option><option value="Residential Property">Residential Property</option><option value="Stocks">Stocks</option></select></td> | |
</tr> | |
<tr class="fields"> | |
<td class="fields" align="left"><label for="dateJoined_field">Date Joined</label><span class="required">*</span></td> | |
<td align="left"><input type="text" name="dateJoined" id="dateJoined_field" value="" size="20"/></td> | |
</tr> | |
<tr class="fields"> | |
<td class="fields" align="left"><label for="form_active">Active</label> </td> | |
<td align="left"><input type="checkbox" name="active" id="form_active"/></td> | |
</tr> | |
</table> | |
</fieldset> | |
</td> | |
</tr> | |
</table> | |
</td></tr> | |
<tr><td align="left"> | |
<table class="buttons" id="form-buttons"> | |
<tr class="buttons"><td class="buttons"><input type="submit" name="ok" id="form_ok" value=" OK "/></td><td class="buttons"><input type="submit" name="cancel" id="form_cancel" value="Cancel"/></td></tr> | |
</table> | |
</td></tr> | |
</table> | |
</form> | |
</td> | |
</tr> | |
</table> | |
In this example when the OK button is clicked the <tt>onOkClicked()</tt> method is invoked. | |
If the form is valid a new customer object is created and the forms field values are copied | |
to the new object using the Form | |
<a href="click-api/org/apache/click/control/Form.html#copyTo(java.lang.Object)">copyTo()</a> | |
method. The customer object is then saved, the form's field values are cleared and an | |
info message is presented to the user. | |
<p/> | |
If the user clicks on the Cancel button the request is redirected to the applications | |
HomePage. | |
<h3>6.1 Form Layout</h3> | |
In the example above the Form control automatically renders the form and the fields | |
HTML markup. This is a great feature for quickly building screens, and the form control | |
provides a number of layout options. See the Click <a href="examples.html">Examples</a> for an | |
interactive Form Properties demo. | |
<p/> | |
For fine grained page design you can specifically layout form and fields in | |
your page template. See the <a href="controls.html#template-layout">Template Layout</a> | |
section and <a href="click-api/org/apache/click/control/Form.html#form-layout">Form</a> | |
Javadoc for more details. | |
<p/> | |
An alternative approach to page template design is using a programmatic approach. | |
See the <a href="controls.html#programmatic-layout">Programmatic Layout</a> section for more details. | |
</body> | |
</html> |