Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

The GuestBook application allows users to enter comments that appear on a page like a weblog. Drawing the list of comments is very easy with the Wicket ListView component. This example also gives an impression of what form handling is like.

Image Added

As with all examples, you have to put all files in the same package directory. This means putting the markup files and the java files next to one another. It is possible to alter this behavior, but that is beyond the scope of this example.

...

The Comment POJO model is very straightforward (we have omitted the getter/setter code for brevity in this example):

java
Code Block
titelborderStyle
java
Comment.javasolid
package org.apache.wicket.examples.guestbook;

import java.ioutil.SerializableDate;	
import javaorg.apache.utilwicket.DateIClusterable;

public class Comment implements Serializable
{
	public String text;
	public Date date = new Date(); IClusterable
{
	private String text;
	private Date date = new Date();

	public Comment()
	{
	}

	public Comment(final Comment comment)
	{
		this.text = comment.text;
		this.date = comment.date;
	}

	public String getText()
	{
		return text;
	}

	public void setText(String text)
	{
		this.text = text;
	}

	public Date getDate()
	{
		return date;
	}

	public void setDate(Date date)
	{
		this.date = date;
	}

	public String toString()
	{
		return "[Comment date = " + date + ", text = " + text + "]";
	}
}

GuestBook.java

In the file GuestBook.java we have put the Java component code for the guestbook page. This is the homepage for the guestbook application. The page consists of a form for entering new items to the guestbook and a list of repeating markup for showing the guestbook entries.

...

The implementation below obtains the Comment POJO from the list item and adds label components for the date and text of the Comment. This is all accomplished in just a few lines of code.

Code Block
titel
java
javaGuestBook.java
borderStylesolid
package org.apache.wicket.examples.guestbook;

import java.util.DateArrayList;
import java.util.ListDate;
import java.util.VectorList;

import org.apache.commons.lang.StringUtils;
import org.apache.wicket.markupexamples.html.WebPageWicketExamplePage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.basic.MultiLineLabel;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListViewPropertyListView;
import org.apache.wicket.model.PropertyModel;CompoundPropertyModel;
import org.apache.wicket.util.value.ValueMap;


public final class GuestBook extends WebPageWicketExamplePage
{
	/** Use a Vector, as it is synchronized.A global list of all comments from all users across all sessions */
	private static final ListList<Comment> commentList = new VectorArrayList<Comment>();
	private final ListView commentListView;

	/**
	 * Constructor that is invoked when page is invoked without a session.
	 */
	public GuestBook()
	{
		// Add comment form
		add(new CommentForm("commentForm"));

		add(commentListView = new ListView// Add commentListView of existing comments
		add(new PropertyListView<Comment>("comments", commentList)
		{
			@Override
			public void populateItem(final ListItemListItem<Comment> listItem)
			{
				final Comment comment = (Comment)listItem.getModelObject();
				listItem.add(new Label("date", comment.date.toString()));
				listItem.add(new MultiLineLabel("text", comment.text));
			}
		}).setVersioned(false);
	}

	/**
	 * A form that allows a user to add a comment.
	 * 
	 * @author Jonathan Locke
	 */
	public final class CommentForm extends FormForm<ValueMap>
	{
		/**
		 * Constructor
		 * 
		 * @param id
		private final Comment comment = new Comment();
 *            The name of this component
		 */
		public CommentForm(final String componentNameid)
		{
			// Construct form with no validation listener
			super(componentName(id, new CompoundPropertyModel<ValueMap>(new ValueMap()));

			// this is just to make the unit test happy
			setMarkupId("commentForm");

			// Add text entry widget
			add(new TextAreaTextArea<String>("text", new PropertyModel(comment, "text")).setType(String.class));

			// Add simple automated spam prevention measure.
			add(new TextField<String>("comment").setType(String.class));
		}

		/**
		 * Show the resulting valid edit
		 */
		@Override
		public final void onSubmit()
		{
			final Comment newCommentValueMap values = getModelObject();

			// check if the honey pot is filled
			if (StringUtils.isNotBlank((String)values.get("comment")))
			{
				error("Caught a spammer!!!");
				return;
			}
			// Construct a copy of the edited comment
			Comment comment = new Comment();

			// Set date of comment to add
			newCommentcomment.text = comment.text;

setDate(new Date());
			comment.setText((String)values.get("text"));
			commentList.add(0, newCommentcomment);

			// Clear out the text component
			commentListViewvalues.modelChanged(put("text", "");
		}
	}

		comment.text = "";
		}/**
	 * Clears the comments.
	 */
	public static void clear()
	{
		commentList.clear();
	}
}

When the CommentForm is submitted, the onSubmit() method is called. Notice that nothing gets the value of the TextArea that was added in the CommentForm constructor. This is because the comment is the model and the third parameter to the TextArea constructor specified the property of the model to update. So all onSubmit() has to do is create a new comment from the model that was updated and add it to the comment list. When the page redraws, the new list will be rendered.

...

Finally, notice the <wicket:remove> block. This is simply markup that is there for previewing purposes only. When the page renders, it is stripped out.

Code Block
html
html
titelGuestBook.html
borderStylesolid

<html>
<body>

<html xmlns:wicket="http://wicket.apache.org/">
<head>
	<title>Wicket Examples - guestbook</title>
	<link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
  <span wicket:id="mainNavigation"/>

  <form wicket:id = "commentForm" id = "commentForm">
    Add your comment here:
    <p>
    <textarea wicket:id = "text">This is a comment</textarea>
    <input type="text" wicket:id="comment" class="nospam" onfocus="getElementById('formsubmit').focus();"/>
    <p>
    <input type = "submit" value = "Submit" id="formsubmit"/>
  </form>
  <p><p/>
  <span wicket:id = "comments" id="comments">
    <p>
	    <span wicket:id = "date">1/1/2004</span><br>
	    <span wicket:id = "text">Comment text goes here.</span>
	</p>
  </span>
  <wicket:remove>
    <p>
	    1/2/2004<br/>
	    More comment text here.
    </p>
  </wicket:remove>
</body>
</html>

...

For completeness, we've included the GuestBookApplication class, and as a final treat the modifications to the web.xml file.

Code Block
java
java
titelGuestBookApplication.java
borderStylesolid
package org.apache.wicket.examples.guestbook;

import org.apache.wicket.protocol.http.WebApplication.Page;
import org.apache.wicket.examples.WicketExampleApplication;

public class GuestBookApplication extends WebApplicationWicketExampleApplication
{
	/**
	 *   Constructor
	 */
	public GuestBookApplication()
    	{

    }
    
    public Class getHomePage()
    {
        	}

	/**
	 * @see org.apache.wicket.Application#getHomePage()
	 */
	@Override
	public Class< ? extends Page> getHomePage()
	{
		return GuestBook.class;
    	}
}

web.xml

Add the following two sections (servlet and servlet-mapping) to your web.xml file for running this application.

Code Block
titelborderStyle
xmlxml
web.xmlsolid
<servlet>
  <servlet<filter>
	<filter-name>GuestBookApplication</servletfilter-name>
  <servlet-class>wicket	<filter-class>org.apache.wicket.protocol.http.WicketServlet<WicketFilter</servletfilter-class>
  	<init-param>
  	  <param-name>applicationClassName</param-name>
	    <param-value>wicketvalue>org.apache.wicket.examples.guestbook.GuestBookApplication</param-value>
  	</init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>GuestBookApplication</servlet-name>
  <url-pattern>/app/*</url-pattern>
</servlet-mapping>
</filter>