Wicket 10: Form binding with a value object


This is part 10 of a series about Wicket.

We need to collect user input about persons. This input will be passed to another page, so we’ll build two of them: Input that accepts user input and Output that displays the result.

Each person has a name and an age.

public class Person implements Serializable {
   private String name;
   private Integer age;

   // getters and setters
}

Output

Output.html simply displays the values of a Person.

  Hello <span wicket:id="name"></span>, you are <span wicket:id="age"></span> years old!

Output.java receives a Person,

public Output(Person person) {
}

and makes its values available to the markup.

public Output(Person person) {
   add(new Label("name", person.getName()));
   add(new Label("age", String.valueOf(person.getAge())));
}

Input

Input.html has a form. The trick is to use the exact name of the fields in the HTML form.

<form wicket:id="form">
  Name <input type="text" wicket:id="name" /><br />
  Age <input type="text" wicket:id="age" /><br />
  <input type="submit" value="OK" />
</form>

So the form has the same fields with the same name as the value object.

Input.java has the same form,

Form form = new Form("form") {
   protected void onSubmit() {
      // redirect to the Output page
   }
};

that should redirect to the Output page

Person person = new Person();
Form form = new Form("form") {
   protected void onSubmit() {
      setResponsePage(new Output(person));
   }
};

and should automatically bind user input to the value object.

Person person = new Person();
Form form = new Form("form", new CompoundPropertyModel(person)) {
   protected void onSubmit() {
      setResponsePage(new Output(person));
   }
};

Complete code

Input.html

<html>
  <body>
    <form wicket:id="form">
      <table>
        <tr><td>Name</td><td><input type="text" wicket:id="name" /></td></tr>
        <tr><td>Age</td><td><input type="text" wicket:id="age" /></td></tr>
        <tr><td colspan="2"><input type="submit" value="OK" /></td></tr>
      </table>
    </form>
  </body>
</html>

Input.java

public class Input extends WebPage {
   private Person person = new Person();
   public Input() {
      final Form form = new Form("form", new CompoundPropertyModel(person)) {
         protected void onSubmit() {
            setResponsePage(new Output(person));
         }
      };
      final TextField name = new TextField("name");
      final TextField age = new TextField("age");
      form.add(name);
      form.add(age);
      add(form);
   }
}

Output.html

<html>
  <body>
    Hello <span style="color:coral" wicket:id="name"></span>, 
    you are <span wicket:id="age"></span> years old!
  </body>
</html>

Output.java

public class Output extends WebPage {
   public Output(Person person) {
      add(new Label("name", person.getName()));
      add(new Label("age", String.valueOf(person.getAge())));
   }
}

Result

Let’s type something,

The user enters some data

The user enters some data

and submit.

The result

The result

Review

  • A Serializable value object is passed between two pages.
  • The value object is automatically filled with the values of the form using a CompoundPropertyModel.
  • The value object is bound to the form.

Here’s an elegant alternative coding style.

   IModel<Person> model = new CompoundPropertyModel<Person>(new Person());
   final Form form = new Form("form", model) {
      protected void onSubmit() {
         setResponsePage(new Output(model.getObject()));
      }
   };

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: