At line 21 changed 1 line. |
Implementing validation with Tapestry is quite simple. Rather than using a [TextField|http://jakarta.apache.org/tapestry/doc/ComponentReference/TextField.html] component, you use a [ValidField|http://jakarta.apache.org/tapestry/doc/ComponentReference/ValidField.html] components. The validation integration for the personForm.html page is already done by AppGen in the personForm.page. If you open web/pages/personForm.page, you should see the following XML. I've highlighted the portions that are relevant to validation. |
Implementing validation with Tapestry is quite simple. All you need to do is configure a "validators" property on your [TextField|http://jakarta.apache.org/tapestry/doc/ComponentReference/TextField.html] components. The validation integration for the personForm.html page is already done by AppGen in the personForm.page. If you open web/pages/personForm.page, you should see the following XML. |
At line 23 changed 33 lines. |
<pre> |
<?xml version="1.0"?> |
<!DOCTYPE page-specification PUBLIC |
"-//Apache Software Foundation//Tapestry Specification 3.0//EN" |
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd"> |
|
<page-specification class="org.appfuse.webapp.action.PersonForm"> |
<span style="background-color: yellow"><bean name="delegate" class="org.appfuse.webapp.action.Validator"/></span> |
|
<span style="background-color: yellow"><bean name="requiredValidator" class="org.apache.tapestry.valid.StringValidator"></span> |
<span style="background-color: yellow"><set-property name="required" expression="true"/></span> |
<span style="background-color: yellow"><set-property name="clientScriptingEnabled" expression="true"/></span> |
<span style="background-color: yellow"></bean></span> |
|
<property-specification name="person" type="org.appfuse.model.Person"/> |
<property-specification name="personManager" type="org.appfuse.service.PersonManager"> |
global.appContext.getBean("personManager") |
</property-specification> |
<property-specification name="message" type="java.lang.String"/> |
|
<span style="background-color: yellow"><component id="firstNameField" type="ValidField"></span> |
<span style="background-color: yellow"><binding name="value" expression="person.firstName"/></span> |
<span style="background-color: yellow"><binding name="validator" expression="beans.requiredValidator"/></span> |
<span style="background-color: yellow"><message-binding name="displayName" key="person.firstName"/></span> |
<span style="background-color: yellow"></component></span> |
|
<span style="background-color: yellow"><component id="lastNameField" type="ValidField"></span> |
<span style="background-color: yellow"><binding name="value" expression="person.lastName"/></span> |
<span style="background-color: yellow"><binding name="validator" expression="beans.requiredValidator"/></span> |
<span style="background-color: yellow"><message-binding name="displayName" key="person.lastName"/></span> |
<span style="background-color: yellow"></component></span> |
</page-specification> |
</pre> |
{{{<?xml version="1.0" encoding="UTF-8"?> |
<!DOCTYPE page-specification PUBLIC |
"-//Apache Software Foundation//Tapestry Specification 4.0//EN" |
"http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd"> |
At line 28 added 27 lines. |
<page-specification class="org.appfuse.webapp.action.PersonForm"> |
<inject property="engineService" object="engine-service:page"/> |
<inject property="request" object="service:tapestry.globals.HttpServletRequest"/> |
<inject property="response" object="service:tapestry.globals.HttpServletResponse"/> |
<inject property="personManager" type="spring" object="personManager"/> |
|
<bean name="delegate" class="org.appfuse.webapp.action.Validator"/> |
<property name="message" persist="flash"/> |
|
<component id="personForm" type="Form"> |
<binding name="delegate" value="ognl:beans.delegate"/> |
<binding name="clientValidationEnabled" value="true"/> |
</component> |
|
<component id="firstNameField" type="TextField"> |
<binding name="value" value="person.firstName"/> |
<binding name="validators" value="validators:required"/> |
<binding name="displayName" value="message:person.firstName"/> |
</component> |
<component id="lastNameField" type="TextField"> |
<binding name="value" value="person.lastName"/> |
<binding name="validators" value="validators:required"/> |
<binding name="displayName" value="message:person.lastName"/> |
</component> |
|
</page-specification>}}} |
|
At line 59 changed 1 line. |
There are a [number of different validators|http://jakarta.apache.org/tapestry/doc/ComponentReference/ValidField.html] you can use, this example just shows a way to validate Strings are entered. The userForm.page has examples of an EmailValidator and a PatternValidator. All input fields generated by AppGen are required by default. You can change this by modifying the extras/appgen/src/**/*_page.xdt files. |
There are a [number of different validators|http://jakarta.apache.org/tapestry/UsersGuide/validation.html] you can use, this example just shows a way to validate Strings are entered. The userForm.page has examples of an EmailValidator and a PatternValidator. All input fields generated by AppGen are required by default. You can change this by modifying the extras/appgen/src/**/*_page.xdt files. |
At line 65 changed 1 line. |
if (getValidationDelegate().getHasErrors()) { |
if (getDelegate().getHasErrors()) { |
At line 71 changed 1 line. |
Since validation is configured in the page-specification file (a.k.a. personForm.page), whenever a field uses the ValidField component, it will get validated. For those fields that don't have validation, make sure and use the @Label component for its label. Below is a non-validated field example from web/pages/userForm.html. |
Since validation is configured in the page-specification file (a.k.a. personForm.page), whenever a field specifies a "validators" property. For those fields that don't have validation, make sure and use the @Label component for its label. Below is a non-validated field example from web/pages/userForm.html. |
At line 200 added 2 lines. |
import org.apache.tapestry.engine.RequestCycle; |
import org.appfuse.service.Manager; |
At line 203 removed 1 line. |
import org.appfuse.service.PersonManager; |
At line 204 added 3 lines. |
import java.util.HashMap; |
import java.util.Map; |
|
At line 208 changed 4 lines. |
protected void setUp() throws Exception { |
super.setUp(); |
page = (PersonList) getPage(PersonList.class); |
|
protected void onSetUpBeforeTransaction() throws Exception { |
super.onSetUpBeforeTransaction(); |
At line 213 changed 2 lines. |
page.setPersonManager((PersonManager) ctx.getBean("personManager")); |
page.setRequestCycle(getCycle(request, response)); |
Map map = new HashMap(); |
map.put("personManager", (Manager) applicationContext.getBean("personManager")); |
page = (PersonList) getPage(PersonList.class, map); |
At line 217 changed 2 lines. |
protected void tearDown() throws Exception { |
super.tearDown(); |
protected void onTearDownAfterTransaction() throws Exception { |
super.onTearDownAfterTransaction(); |
At line 223 changed 3 lines. |
MockRequestCycle cycle = (MockRequestCycle) page.getRequestCycle(); |
cycle.addServiceParameter(new Long(1)); |
|
RequestCycle cycle = new MockRequestCycle(); |
cycle.setServiceParameters(new Object[] {new Long("1")}); |
At line 227 removed 1 line. |
|
At line 232 changed 3 lines. |
PageEvent event = new PageEvent(page, page.getRequestCycle()); |
page.pageBeginRender(event); |
assertTrue(page.getPeople().size() >= 1); |
assertTrue(page.getPersons().size() >= 1); |
At line 242 changed 1 line. |
Create src/web/**/action/PersonList.java. It should implement [PageRenderListener|http://jakarta.apache.org/tapestry/doc/api/org/apache/tapestry/event/PageRenderListener.html] and read as follows: |
Create src/web/**/action/PersonList.java. It should implement [PageBeginRenderListener|http://jakarta.apache.org/tapestry/tapestry/apidocs/org/apache/tapestry/event/PageBeginRenderListener.html] and read as follows: |
At line 251 removed 2 lines. |
import org.apache.tapestry.event.PageEvent; |
import org.apache.tapestry.event.PageRenderListener; |
At line 257 changed 1 line. |
public abstract class PersonList extends BasePage implements PageRenderListener { |
public abstract class PersonList extends BasePage { |
At line 259 removed 3 lines. |
public abstract void setPersonManager(PersonManager manager); |
public abstract List getPeople(); |
public abstract void setPeople(List people); |
At line 263 changed 2 lines. |
public void pageBeginRender(PageEvent event) { |
setPeople(getPersonManager().getPeople(null)); |
public List getPersons() { |
return getPersonManager().getPeople(); |
At line 266 changed 1 line. |
|
|
At line 268 changed 2 lines. |
Object[] parameters = cycle.getServiceParameters(); |
Long id = (Long) parameters[0]; |
Object[] parameters = cycle.getListenerParameters(); |
Long personId = (Long) parameters[0]; |
At line 272 changed 1 line. |
log.debug("fetching person with id: " + id); |
log.debug("fetching person with personId: " + personId); |
At line 275 changed 2 lines. |
Person person = getPersonManager().getPerson(id.toString()); |
|
Person person = getPersonManager().getPerson(personId); |
|
At line 297 removed 4 lines. |
Change it in personList.page too: |
|
{{{<property-specification name="people" type="java.util.List"/>}}} |
|
At line 319 changed 1 line. |
{{{<verifytitle description="display Main Menu" text=".*${mainMenu.title}.*" regex="true"/>}}} |
{{{<verifyTitle description="display Main Menu" text=".*${mainMenu.title}.*" regex="true"/>}}} |
At line 323 changed 1 line. |
{{{{{{<verifytitle description="Person List appears if save successful" text=".*${personList.title}.*" regex="true"/>}}}}}} |
{{{{{{<verifyTitle description="Person List appears if save successful" text=".*${personList.title}.*" regex="true"/>}}}}}} |
At line 389 changed 1 line. |
<Menu name="PeopleMenu" title="menu.viewPeople" forward="viewPeople"/> |
<Menu name="PeopleMenu" title="menu.viewPeople" page="/people.html"/> |