Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

For example, a Login page, which collects a user name and a password, might look like:

Code Block
languagejava
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
languagexml
<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.

...