...
For example, a Login page, which collects a user name and a password, might look like:
Code Block | ||
---|---|---|
| ||
package com.example.newapp.pages; import com.example.newapp.services.UserAuthenticator; import org.apache.tapestry5.annotations.*; import org.apache.tapestry5.corelib.components.Form; import org.apache.tapestry5.corelib.components.PasswordField; import org.apache.tapestry5.ioc.annotations.Inject; public class Login { @Persist @Property private String userName; @Property private String password; @Inject private UserAuthenticator authenticator; @InjectComponent("password") private PasswordField passwordField; @Component private Form formloginForm; /** * Do the cross-field validation */ void onValidateFromLoginForm() { if (!authenticator.isValid(userName, password)) { // record an error, and thereby prevent Tapestry from emitting a "success" event formloginForm.recordError(passwordField, "Invalid user name or password."); } } /** * Validation passed, so we'll go to the "PostLogin" page */ Object onSuccess() { return PostLogin.class; } } |
Wiki Markup |
---|
{float:right|width=40%} {info} Note that the onValidateFromLoginForm() and onSuccess() methods are not public; event handler methods can have any visibility, even private. Package private (that is, no modifier) is the typical use, as it allows the component to be tested, from a test case class in the same package. {info} {float} |
...
Code Block | ||
---|---|---|
| ||
<html t:type="layout" title="newapp com.example"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<div class="row">
<div class="span4 offset3">
<t:form t:id="loginForm">
<h2>Please sign in</h2>
<t:textfield t:id="userName" t:mixins="formgroup" validate="required"/>
<t:passwordfield t:id="password" value="password" t:mixins="formgroup" validate="required"/>
<t:submit class="btn btn-large btn-primary" value="Sign in"/>
</t:form>
</div>
</div>
</html>
|
The Tapestry Form component is responsible for creating the necessary URL for the form submission (this is Tapestry's responsibility, not yours).
For the TextField, we provide a component id, userName. We could specify the value
parameter, but the default is to match the TextField's id against a property of the container, the Login page, if such a property exists.
As a rule of thumb, you should always give your fields a specific id (this id will be used to generate the name
and id
attributes of the rendered tag). Being allowed to omit the value parameter helps to keep the template from getting too cluttered.
...