I've begun work on a (long overdue) reference manual for Wicket, and wanted to get some initial feedback. Is this the kind of manual everybody is longing for?

PS. This is a direct paste from the generated DocBook version, so the markup is not 'optimized' for display within this JRoller template.

Chapter 4. Form Input

Abstract

This chapter shows how you can process input from users using forms, inputs and
other form related components. We show how to add validation to your fields and
give your users feedback when they entered wrong input.

4.1. Introduction

Many webapplications need some sort of user input. This is an integral part
of dynamic web applications. Many web applications don't take localization and
internationalization into account. Often you have to write a lot of code for parsing
request parameters, validating and converting them into the actual types your
POJOs use.

With Wicket things will be different: you won't have to write lots and lots of
scaffolding: Wicket takes care of a lot of things: updating your POJOs,
converting the user input taking localization into account, validating the input,
displaying internationalized messages when the input isn't valid, etc.

4.2. Form Components

Most, if not all, Wicket form components will be discussed in the following sections. The
goal is not to be complete and show all possible uses of each component, but to give an
initial outline of how such a component can be used. For more information, please look in
the JavaDoc of the components.

4.2.1. Form

The
Form
component is a container for your form components. In the markup a form looks
like this:

...

To implement a form, subclass the
Form
, add FormComponents (such as CheckBoxes, ListChoices or TextFields) to the form
and override the
onSubmit
method. You can nest multiple buttons if you want to vary submit behaviour.
However, it is not necesary to use Wicket's button class, just putting e.g.


suffices.

public class MyForm extends Form {
    public MyForm(String id, IModel model, IFeedback feedback) {
        // add (form) components
    }
    public void onSubmit() {
        // handle the submission of the form.
    }
    public void onError() {
        // do something special when an error occurs,
        // instead of displaying messages.
    }
}

Wicket will call onSubmit when the user input is
valid. When one or more child components of the form fails to validate,
Wicket will call onError. Wicket also supports
multiple buttons, which are discussed later.

4.2.2. TextField

A TextField receives user input in possibly its
most basic form: a single line of text. The markup for a
TextField component must be a
<input type="text" ... /> tag, otherwise Wicket
will throw an exception.

The markup for a textfield looks as follows:

...

In the Java code you can use several constructors for the component, depending
on the type of model you want to bind to the textfield.

public MyForm(String id, IModel model, IFeedback feedback) {
    super(id, model, feedback);
    add(new TextField("textField", new PropertyModel(model, "name")));
    ...
}

It is possible to use the true types of the fields in the textfield component.
Say that you need an integer value. Instead of performing the dataconversion
yourself, you specify for Wicket that you require an integer value by adding
an extra parameter to the TextField constructor: the
type of the property.

new TextField("integerField", new PropertyModel(model, "myInt"), Integer.class)

More information on this subject is provided in the validation section later on.

4.2.3. PasswordTextField

The PasswordTextField component is used for users to enter
their passwords. The field can be used in both login forms and registration forms.
In login forms it is usually required that the password is always cleared when the
page is rendered. When editing account information, this is not the case, so the
password field can be told not to clear the field when rendered. The markup looks
like this (the type="password" is required!):

The corresponding Java declaration looks like this:

PasswordTextField pwd = new PasswordTextField("pwd", new PropertyModel(model, "myPwd"));

When you want to use the field in a registration form, or some other form where the
password should not be reset on each render, you have to set the reset password flag
to false:

pwd.setResetPassword(false);

The default is to clear the field each time it is rendered.

4.2.4. TextArea

The TextArea component is a multi-line text editing component.
The component requires to be attached to a ...

The corresponding Java code looks like this:

TextArea area = new TextArea("myTextArea", new PropertyModel(model, "text"));

If you have to programmatically alter the rows or cols

attributes of the tag, then you can add AttributeModifiers
to the TextArea in order to produce the required effect:

area.add(new AttributeModifier("rows", 10));

4.2.5. CheckBox

The CheckBox component displays a checkbox. The checkbox can
either be checked or not, corresponding to a true or falseconstant>

value for the bound model. The CheckBox requires to be attached
to a input field whose type is 'checkbox':

...

The corresponding Java code:

CheckBox check = new CheckBox("myCheckbox", new PropertyModel(model, "boolValue"));

It is also possible to have the CheckBox respond directly to changes. Wicket will add
a small piece of JavaScript in order to generate the onSelectionChanged(Object newSelection)
event.

CheckBox check = new CheckBox("myCheckbox", new PropertyModel(model, "boolValue")) {
    protected boolean wantOnSelectionChangedNotifications() {
        return true;
    }
    protected void onSelectionChanged(Object newSelection) {
        Boolean value = (Boolean)newSelection;
        if(value.boolValue()) {
            // do something
        }
    }
};

4.2.6. RadioChoice

The RadioChoice component creates a number of radiobuttons
on your form. The RadioChoice requires both a model to bind the
value in, and a list of choices to display and select from. The list of choices can
come from a database or be filled from your Java code.
It requires an input markup tag of type 'radio':

...

When you have a list filled with the strings 'foo' and 'bar', and you supply the
RadioChoice with that list, Wicket will generate each choice for you in the final
markup.

public MyForm(String id, IModel model, IFeedback feedback) {
    super(id, model, feedback);
    List choices = new ArrayList();
    choices.add("foo");
    choices.add("bar");
    add(new RadioChoice("myRadio", new PropertyModel(model, "foobar"), choices));
}

It is possible to construct more advanced methods of binding and creating selection
choices. See the chapter on database applications for more information.

4.2.7. ListChoice

This component shows a plain listbox filled with the choices to choose from. The
component only supports single selection values. When the number of choices is bigger than
the number of displayed values, a scrollbar is shown (by the browser). The required markup
looks like this:

...

The size attribute is merely for previewing purposes. Wicket will add the
attribute when it is not present. The Java code for creating a ListChoice:

public MyForm(String id, IModel model, IFeedback feedback) {
    List choices = new ArrayList();
    choices.add("foo");
    choices.add("bar");
    ListChoice lc = new ListChoice("myListChoice", new PropertyModel(model, "foobar"), choices);
    lc.setMaxRows(2);
    add(lc);
    ...
}

4.2.8. ListMultipleChoice

This component shows a plain listbox filled with the choices to choose from. The
component supports multiple selection values. When the number of choices is bigger than
the number of displayed values, a scrollbar is shown (by the browser). The required markup
looks like this:

...

The component needs a java.util.Collection as the model object,
in order to supply your object with the multiple choices. The Java code for this component
looks like:

public MyForm(String id, IModel model, IFeedback feedback) {
    List choices = new ArrayList();
    choices.add("foo");
    choices.add("bar");
    MultiListChoice lc = new MultiListChoice("myMultiListChoice", new PropertyModel(model, "foobarList"), choices);
    add(lc);
    ...
}

4.2.9. DropDownChoice

This component shows a dropdown box filled with the choices to choose from. The selected value
during rendering is the value of the model object. When the selection is changed, the selected
value is set on the model object. The required markup looks like this:

...

The corresponding Java code looks like:

public MyForm(String id, IModel model, IFeedback feedback) {
    List choices = new ArrayList();
    choices.add("foo");
    choices.add("bar");
    DropDownChoice lc = new DropDownChoice("myDropDownChoice", new PropertyModel(model, "foobar"), choices);
    add(lc);
    ...
}

The DropDownChoice also supports listening to
onchange events on the clientside, like the CheckBox
does. Wicket will add a small piece of JavaScript in order to generate the
onSelectionChanged(Object newSelection) event.

DropDownChoice choice = new DropDownChoice("myDropDownChoice", new PropertyModel(model, "foobar"), choices) {
    protected boolean wantOnSelectionChangedNotifications() {
        return true;
    }
    protected void onSelectionChanged(Object newSelection) {
        // do something
    }
};