You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

excerpt:hidden=true}How to add a variable/run-time-determined number of components

Table of contents

= Repeaters =

e.g. A ListView in core or a number of components in the

wicket-extensions repeaters

package.

A repeater is Wicket's way of doing loops and allows the user to add a series of items
or components where the number of items is not available at design-time.

Summary

Code:

{panel}
    List list = Arrays.asList(new String[]{"a", "b", "c"});
    ListView listview = new ListView("listview", list)
    {
{panel}
	    protected void populateItem(ListItem item)
	    {
		    item.add(new Label("label", item.getModel()));
	    }
{panel}
    };
{panel}

Markup:

<span wicket:id="listview">
{panel}
   this label is: <span wicket:id="label">label</span><br/>
{panel}
</span>

will result in the following redering to the browser:

<span wicket:id="label">a</span><br/>
<span wicket:id="label">b</span><br/>
<span wicket:id="label">c</span><br/>

You can also put formcomponents into the repeaters, you bind their values through IModel just as if they were in a regular form.

Note

There are a few provisions you have to take care of when using a repeater in the form. Usually repeaters clear out their items at the beginning of every request, when inside a form this is usually undesirable because you want to preserve the old items because you want them to keep their state as opposed to being recreated fresh.

ListView, for example, has ListView.setReuseItems(true); which should be called when inside the form so that it preserves old items instead of always creating new ones.

ListView Table Example

Lets take a simple example, we want to show a table of users:

<table>
{panel}
  <tr wicket:id="listview">
    <td><span wicket:id="firstname"></span></td><td><span wicket:id="lastname"></span></td>
  </tr>
{panel}
</table>

<p>
What we want is everything within

<tr>...</tr>

to repeat once for every user, so we attach ListView to the

tr

tag.
</p><p>
What ListView does is make its immediate children believe that their markup is that of the ListView itself, so each immediate child believes that it is attached to the <tr wicket:id="listview"> tag.
</p>
We need to represent these immediate ListView children with a container component, because each of these children may contain multiple children of its own, in our case the firstname/lastname labels. This is what the listitem is, its a simple WebMarkupContainer created for you so you don't have to do it everytime yourself.

So we will have a listitem container created for every list item in the list that feeds the listview. but this is not enough, as each of these listitems must contain the components that represent data within it (the firstname, lastname labels that we want to add).

This is where populateItem comes in, it is called once for every listitem created and allows you to add components to it, so the listview render process looks like this:

before each render:
{panel}
  clear all children
  for every list item in the list:
     create a ListItem webmarkupcontainer
     add created ListItem as a child
     call populateItem with the created ListItem container to allow users to populate it
{panel}
render:
{panel}
  render all immediate children with own markup
{panel}

i.e. you just write...

add(new ListView("listview", list)
{
	protected void populateItem(ListItem item)
	{
		User user = (User)item.getModelObject();
		item.add(new Label("firstname", user.getFirstname()));
		item.add(new Label("lastname", user.getLastname()));
	}
});

Example Details

In this example,

User

is defined as:

{panel}
  class User
  {
    String _first, _last;
{panel}

{panel}
    public User(String _first, String _last)
    {
      this._first = _first;
      this._last = _last;
    }
{panel}

{panel}
    public String getFirstname() { return _first; }
    public String getLastname() { return _last; }
  }
{panel}

and the (java.util.List )

list

is initialised as follows:

List list = Arrays.asList(
new User[]

Unknown macro: { new User("FirstA", "LastA"), new User("FirstB", "LastB"), new User("FirstC", "LastC") }

);


Added by Gwyn 11:26, 8 May 2006 (BST) but Igor Vaynberg did all the hard workl I just copied from his mailing list posts!

  • No labels