| <!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> |