Hello Visitor 🙂 In previous posts we created base project and added common layout to ItemDirectory Wicket application. Today we are going to add first form to allow users to insert some data into our application.

As main feature of ItemDirectory is to manage information where items (books, movies, music, postage stamps) are stored in our home/work, the first data we need to know are locations where we actually can store those things. So we start with adding table, entity and form to manage locations of our precious items.

Database, entity and DAO

First thing we need is locations table in database and entity mapping class:

Create table script listing:

Entity class listing:

As you can see, Location class is very simple: only one field, but the only thing we want at the moment from this entity is a name describing where item is stored. Is it “Bookcase in living room, second drawer from the top” or “Cabinet in the saloon, top bookshelf”.

After creating table and entity we have to prepare DAO and service layer. As it is not closely connected with Wicket I will skip this part, but those more interested in it can find details in this changeset in the repository.

Add Location Wicket Pages

We start with LocationsPage which will, in the future, show listing with all locations available. For now, page will display number of locations in the database (very similar to users counter in the HomePage) just to show that creating new location was successful.

Listings of LocationsPage java and HTML files:

If you were cautious enough you probably noticed a link I didn’t mentioned earlier. It’s a simple link redirecting user to AddLocationPage when clicked (see overriden method onClick()).

Next we add link to LocationsPage in the BasePage to appear on the topbar. In BasePage.html we add Wicket placeholder for this link:

and in corresponding Java class add line:

Everything seems to be ok, you can do mvn jetty:run to see the results, but one thing could be easily improved, the URL address of LocationsPage. Instead of ugly one:

http://localhost:9090/item-directory/?wicket:bookmarkablePage=:pl.tomaszdziurko.itemdirectory.web.view.locations.LocationsPage

after adding one line to Application class:

we configure Wicket to:

Easy! 🙂

Changes from this part can be viewed in these two changesets: [1], [2]

Add location form

Now it’s time to start with main part of this post: html form to add new location. First step is to add placeholders in AddLocationsPage.html:

Second step is to create components in Java class:

HTML file is rather self-explanatory: simple form with one input field and submit button. But java page class needs more elaborate explanation:

In (1) we create Wicket form with model to gather data from user. We use CompoundPropertyModel which automatically connects components with properties of model object with the same id/name. In our page model object is AddLocationPage itself and its name field (with usage of Compound model) works as a model for TextField component with id name.

Concept of models is one of the most important element of Wicket and you should understand what models do and how they work. In this tutorial I am concentrating on practical usage of Wicket, so theory isn’t covered in great detail.
Although you can read more about models on two [[1]](https://cwiki.apache.org/WICKET/working-with-wicket-models.html) and [[2]](https://cwiki.apache.org/WICKET/more-on-models.html). Wiki pages and generally in two presentations by Mystic Coders. Links to them can by found in the “Tutorial, guides” section in [Wicket – useful links](/2010/02/wicket-useful-links/) post

In (2), (3) and (4) we create and add to our form: label for input field, input field (note that its called name, as property in page class) and submit button with overriden onSubmit method in which we place save logic.

This part of tutorial can be viewed in this changeset.

Validating and saving data

After we created form next obvious step is to add call to LocationService.save method. But before that we must validate user input to check if it is correct and won’t blow our application out 🙂 You can easily do it with leaving name empty and submitting a form: exception deep from Hibernate internals in your face 🙂

So we must add some validators first:

  1. Name field should be required
  2. Name field length should be between 4 and 255.
  3. There should be only one location with the same name (check unique constraint on locations table).

Required text field

There are two ways to make field required: you can call TextField.setRequired(true) or you can replace TextField component with RequiredTextField one. In our application I chose the latter.

String length validation

Adding length validation in Wicket is very, very easy. We use StringValidator and one of its nested classes: ExactLengthValidator, LengthBetweenValidator, MaximumLengthValidator or MinimumLengthValidator. In our case java code looks like that:

Unique location name validator

This validator needs longer explanation as it will be our first custom validator and it will be covered in the next post as I am now going to talk about showing error messages and saving location in the database to finish with almost perfectly working (except non-unique names) form in ItemDirectory web appplication.

Show user what’s wrong or what’s ok

Now, when we have some validation it would be cool to be able to tell user what he did wrong or when his action performed successfully. In Wicket there is component dedicated to showing feedback to user: FeedbackPanel. And as we will be potentially used in every page we will add it in BasePage class:

 

And how is it working? When validation fails on any validator, it adds message to feedback panel and rerenders page. Then, on rerender, messages are flushed and showed to the user on Error level (there are three levels: Info, Warn, Error which render in different css styles so their look can be customized). Ok, so far so good but what if we want to add such info manually? No problem, we will do this when succesfull save of Location object occurs. In this step we also add call to LocationService.save method to actually save new Location object in database.

Every Wicket component has three methods info(String message), warn(…), error(…) which add feedback message for component and they are very useful for validating data, etc. However, if we want to redirect user to another page and show message there, we must use another way of adding feedback messages, based on user session and not on current component as component messages won’t be rendered after redirect to other page. That’s why we use getSession().info(…);
If you try with only info(…) you will get warning in the log:

And after this we will see that everything is working as expected:

Summary

Ok, we reached the end of this post. We now have working Wicket form in our application. In next episode we will create custom validator to prevent adding non-unique location names.  Of course as always you can download latest source code from here. Hope you will be here for the next part of Wicket tutorial 🙂