Here we will create a form, that accepts a mandatory number as input and returns the input as result when the validation succeeds. The value will be stored into a ZProperty object, that performs validation and conversion to a number.
This example separates the action and the view pojo. It is possible to merge them into one object. It's up to you, how you like to use the framework.
- First create empty application
- create tutorial/WEB-INF/classes/org/ztemplates/tutorial/forms/search where you will put all the files defined below
- create a file called PropertySearchForm.vm in with the following content. Standard webform with one text-input-field called 'id' and a operation 'submit'
<html>
<form>
<table border="0" cellspacing="5" cellpadding="5">
<tr>
<th valign="middle">Id:</th>
<td><input type="text" name="id" value="$!{id}" /></td>
<td>$!{id.state}</td>
</tr>
<tr>
<td><input type="submit" value="Search" name="submit" /></td>
</tr>
</table>
</form>
<p>
$!{result}
</html>
This is the view template. Velocity will fill the ${...} with the values provided by the render-pojo.
- Create a file called PropertySearchForm.java with the following content. Note it has the same name and the same location as the template file. By convention the renderer searches for the template file at the same location as the annotation. See @ZTemplate for how to override the default behavior.
package org.ztemplates.tutorial.forms.property;
import org.ztemplates.property.ZError;
import org.ztemplates.property.ZIntProperty;
import org.ztemplates.property.ZOperation;
import org.ztemplates.render.ZExpose;
import org.ztemplates.render.ZRenderer;
import org.ztemplates.render.velocity.ZVelocityRenderer;
@ZRenderer(ZVelocityRenderer.class)
public class PropertySearchForm {
//property takes care of conversion to integer and validation.
private final ZIntProperty id = new ZIntProperty() {
@Override
public ZError validate() {
ZError error = super.validate();
if (error != null) {
return error;
}
try {
if (getValue() < 5 || getValue() > 9) {
return new ZError("you must enter number between 5 and 9");
}
return null;
} catch (Exception e) {
return new ZError(e.getMessage());
}
}
};
//constructor says: operation depends on property id,
//so if validation fails on id, operation will also return isError() true
//you can pass many properties to the operation constructor
private final ZOperation submit = new ZOperation(id);
//fake, holds the search result
private String result;
public PropertySearchForm() {
//id is required
id.setRequired(true);
}
public void setResult(String result) {
this.result = result;
}
@ZExpose
public String getResult() {
return result;
}
@ZExpose
public ZIntProperty getId() {
return id;
}
@ZExpose
public ZOperation getSubmit() {
return submit;
}
}
|
As you can see the View-Model has no behavior except validation logic, it is a passive dataholder for the template.
- Create a file called SearchFormAction.java with the following content. The Action is the active part. You place the behavior in callbacks that get called when the url is processed.
package org.ztemplates.tutorial.forms.property;
import org.ztemplates.actions.ZAfter;
import org.ztemplates.actions.ZGetter;
import org.ztemplates.actions.ZMatch;
import org.ztemplates.property.ZIntProperty;
import org.ztemplates.property.ZOperation;
import org.ztemplates.web.ZTemplates;
//match the url /forms/propertysearch, form parameters are id and submit
@ZMatch(value = "/forms/propertysearch", parameters = { "id", "submit" })
public class PropertySearchFormAction {
private PropertySearchForm searchForm = new PropertySearchForm();
//callback, annotation not mandatory as name convention is also used
@ZAfter
public void after() throws Exception {
if (!getId().isError()) {
searchForm.setResult("searched for: " + getId().getValue());
}
// this renders the response and sends it to the web-browser
ZTemplates.getServletService().render(searchForm);
}
//parameters from form object
//annotation not mandatory as name convention applies
@ZGetter("id")
public ZIntProperty getId() {
return searchForm.getId();
}
//parameters from form object
//annotation not mandatory as name convention applies
@ZGetter("submit")
public ZOperation getSubmit() {
return searchForm.getSubmit();
}
}
|
- open a command window and change to the tutorial/WEB-INF/classes directory
- compile the class
javac -cp ../lib/ztemplates.jar tutorial/org/ztemplates/forms/property/*.java