AJAX Form

This page demonstrates how Tapestry AJAX-enables a Form if you specify async="true" on it.

Welcome Humpty Dumpty. Your birthday is Thu Jan 01 00:00:00 UTC 1970
Note that the following time field does not update because it's not in the zone: Sat Dec 21 14:38:07 UTC 2024

References: Form, Ajax and Zones, Zone, AjaxResponseRenderer, Request, @Inject, @InjectComponent, t5/core/zone, t5/core/ajax, t5/core/forms.

Home


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- We need a doctype to allow us to use special characters like &nbsp; 
     We use a "strict" DTD to make IE follow the alignment rules. -->
     
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<body class="container">
    <h3>AJAX Form</h3>

    <noscript class="js-required">
        ${message:javascript_required}
    </noscript>     

    <p>This page demonstrates how Tapestry AJAX-enables a Form if you specify <code>async="true"</code> on it.</p>

    <div class="eg">
        <t:zone t:id="formZone" id="formZone">
            <t:form t:id="ajaxForm" class="form-horizontal" async="true">

                <t:errors globalOnly="true"/>

                <div class="form-group">
                    <t:label for="firstName" class="col-sm-2"/>
                    <div class="col-sm-4">
                        <t:textfield t:id="firstName"/>
                    </div>
                </div>
                <div class="form-group">
                    <t:label for="lastName" class="col-sm-2"/>
                    <div class="col-sm-4">
                        <t:textfield t:id="lastName"/>
                    </div>
                </div>
                <div class="form-group">
                    <t:label for="birthday" class="col-sm-2"/>
                    <div class="col-sm-4">
                        <t:datefield t:id="birthday"/>
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-4 col-sm-offset-2">
                        <t:submit value="Accept"/>
                    </div>
                </div>
    
                Welcome ${name}. Your birthday is ${birthday}
            </t:form>
        </t:zone>
    </div>  

    Note that the following time field does not update because it's not in the zone:  ${serverTime}<br/><br/>
    
    References: 
    <a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/corelib/components/Form.html">Form</a>, 
    <a href="http://tapestry.apache.org/ajax-and-zones.html">Ajax and Zones</a>, 
    <a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/corelib/components/Zone.html">Zone</a>, 
    <a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/services/ajax/AjaxResponseRenderer.html">AjaxResponseRenderer</a>, 
    <a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/services/Request.html">Request</a>, 
    <a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html">@Inject</a>, 
    <a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/annotations/InjectComponent.html">@InjectComponent</a>, 
    <a href="http://tapestry.apache.org/5.4/coffeescript/zone.html">t5/core/zone</a>, 
    <a href="http://tapestry.apache.org/5.4/coffeescript/ajax.html">t5/core/ajax</a>, 
    <a href="http://tapestry.apache.org/5.4/coffeescript/forms.html">t5/core/forms</a>.<br/><br/> 

    <t:pagelink page="Index">Home</t:pagelink><br/><br/>

    <t:tabgroup>
        <t:sourcecodetab src="/web/src/main/java/jumpstart/web/pages/examples/ajax/AjaxForm.tml"/>
        <t:sourcecodetab src="/web/src/main/java/jumpstart/web/pages/examples/ajax/AjaxForm.java"/>
        <t:sourcecodetab src="/web/src/main/resources/META-INF/assets/css/examples/js.css"/>
    </t:tabgroup>
</body>
</html>


package jumpstart.web.pages.examples.ajax;

import java.util.Date;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Size;

import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.Form;
import org.apache.tapestry5.corelib.components.TextField;
import org.apache.tapestry5.corelib.components.Zone;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.ajax.AjaxResponseRenderer;

@Import(stylesheet = "css/examples/js.css")
public class AjaxForm {

    // Screen fields

    @Property
    @NotNull
    @Size(max = 10)
    private String firstName;

    @Property
    @NotNull
    @Size(max = 10)
    private String lastName;

    @Property
    @NotNull
    @Past
    private Date birthday;

    // Generally useful bits and pieces

    @Inject
    private Request request;

    @InjectComponent("ajaxForm")
    private Form form;

    @InjectComponent("firstName")
    private TextField firstNameField;

    @InjectComponent
    private Zone formZone;

    @Inject
    private AjaxResponseRenderer ajaxResponseRenderer;

    // The code

    void setupRender() {
        if (firstName == null && lastName == null && birthday == null) {
            firstName = "Humpty";
            lastName = "Dumpty";
            birthday = new Date(0);
        }
    }

    void onValidateFromAjaxForm() {

        // Note, this method is triggered even if server-side validation has already found error(s).

        if (firstName != null && firstName.equals("Acme")) {
            form.recordError(firstNameField, "First Name must not be Acme.");
        }

    }

    void onSuccess() {
        if (request.isXHR()) {
            ajaxResponseRenderer.addRender(formZone);
        }
    }

    void onFailure() {
        if (request.isXHR()) {
            ajaxResponseRenderer.addRender(formZone);
        }
    }

    public String getName() {
        return firstName + " " + lastName;
    }

    public Date getServerTime() {
        return new Date();
    }

}


.eg {
                margin: 20px 0;
                padding: 14px;
                color: #888;
                border: 1px solid #ddd;
                border-radius: 6px;
                -webkit-border-radius: 6px;
                -mox-border-radius: 6px;
}

.js-required {
                color: red;
                display: block;
                margin-bottom: 14px;
}

.js-recommended {
                color: red;
                display: block;
                margin-bottom: 14px;
}