Wicket provides a set of mechanisms for validating entered data and displaying error messages caused by malformed user input. There are the following two feedback components (see Wicket 1.4.9) which help to show any validation errors.
- org.apache.wicket.markup.html.panel.FeedbackPanel can be placed somewhere on the page and shows a feedback error message for any validation error occurred in a form of the shown page.
- org.apache.wicket.markup.html.form.validation.FormComponentFeedbackBorder encloses one form component/input field and shows a feedback in the case the enclosed component causes a validation error.
The code for the Wicket component described in the following can be downloaded.
Motivation
Recently, I had to implement a system with a complex validation procedure for the entered data using Wicket. The customer had the following requirements:
- The mandatory fields were denoted by an asterisk (*) which resulted in a confusion with the asterisk shown by a FormComponentFeedbackBorder component. The customer wanted rather to indicate a validation error occurred at a component using a different way than showing an asterisk, e.g., by showing components causing a validation error in a different background color.
- Some of the validation steps included form-based validation. This means that several values together form a validation unit. The customer wanted that all fields involved in a form-based validation should visualize the validation error.
Extending the Feedback Mechanism
Consequently, I implemented a new Wicket component that solves the above issues and uses org.apache.wicket.markup.html.form.validation.FormComponentFeedbackBorder as a basis. The implementation provides a container which contains one or more form components that may cause validation errors. Any error is displayed by adding a CSS class visualizing the form element in the container that is responsible for showing the error. The default behavior is that if one or more component contained in the container causes a validation error, all components in the container display the error.
There are four properties that allow one to change this default behavior. The first two allow the user of the feedback component to define which set of components in the feedback container show a validation error:
- It is possible to define a set of components in the container which will show the errors occurring in the container. If this set is defined, any component that is not in this set will not show the error.
- There is a set of elements that explicitly define the components that will show an error, i.e., this is the opposite of 1. Note that either the first way of defining the visualizing components should be used or the second, but not both.
- It is possible to define a set of components contained in the feedback container that will be ignored as a source of validation errors.
- As an opposite way, it is possible to define a set of components that is are observed as a source of validation errors. Note that either the first way of defining the components that are a source of validation errors should be used or the second way, but not both.
Example
The following example is based on a form that queries a user for his/her name and account information. There may be two different types of accounts: first, postal accounts which just ask for an account number and an account holder, and second, bank accounts which ask also for the address of the bank. The following Figure 1 shows a screen shot of the corresponding web form.
Figure 1: A sample application showing a simple web form for entering bank or postal account information.
The application should provide a validation mechanism which checks the following:
- Either the bank account radio button or the postal account radio button must be selected.
- If the bank account is checked, the corresponding fields (account number, address of bank, account holder) are mandatory.
- If the postal account is ticked, the corresponding fields (account number, account holder) are mandatory.
The presented validation feedback container solves the problem. It provides a possibility to nest feedback containers and to use a CSS class to mark all or just a part of the components that caused the validation feedback errors. Figure 2 shows how the provided account information is nested by using this new component.
The outer feedback container is responsible for showing any validation errors occurring for the radio button group containing the choice “Bank Account” and “Postal Account”. It is visualized in the figure by the red box with the number 1. Apart from this feedback container there are five feedback containers for any validation errors occurring in the text fields designated by the red boxes with the numbers 2, 3, 4, 5, and 6.
In the case neither “Bank Account” nor “Postal Account” is chosen and submit is pressed, both labels will be marked with a validation error (see Fig. 3).
In the case “Bank Account” is checked, the fields 2, 3, and 4 are enabled and checked for the correctness when submitting the data. In the case one of these fields cause a validation error when pressing submit, the corresponding fields are marked (Fig. 4).
The equivalent validation feedback behavior is given for “Postal Account” and the corresponding fields (Fig. 5).
Implementing the Example Above
The presented validation feedback container is implemented by the class com.blogspot.m3g4h4rd.wicket.CSSComponentFeedbackContainer and can be found in the archive file (.zip) provided by the link at the end of this article.
The following Wicket-HTML and Java source of the above Web-UI shows how the feedback container is used.
<html>The above Wicket-HTML code contains several >wicket:container< tags that are used to bind the feedback container. The outer container (1) is referred as accountsFeedbackContainer, whereas bankAccountNumberFeedback, bankAddressFeedback, bankAccountHolderFeedback, postalAccountNumberFeedback, and postalAccountHolderFeedback are the (inner) containers 2 – 6 in Fig. 2.
<body>
<wicket:panel>
<!-- Container showing validation errors -->
<wicket:container wicket:id="accountsFeedbackContainer">
<!-- Container for the account radio group -->
<wicket:container wicket:id="accountRadioGroup">
<br/>
<b>
<span wicket:id="accountInformationLabel">
Account Information
</span>
</b>
<table border="0">
<tr>
<td><input type="radio" wicket:id="bankAccount">
<span wicket:id="bankAccountLabel">Bank Account</span>
</td>
<td>
<table border="0">
<tr>
<td>
<span wicket:id="bankAccountNumberLabel">
Bank Account Number:
</span>
</td>
<td>
<wicket:container wicket:id="bankAccountNumberFeedback">
<input wicket:id="bankAccountNumber"/>
</wicket:container>
</td>
</tr>
<tr>
<td>
<span wicket:id="bankAddressLabel">
Address of Bank:
</span>
</td>
<td>
<wicket:container wicket:id="bankAddressFeedback">
<input wicket:id="bankAddress"/>
</wicket:container>
</td>
</tr>
<tr>
<td>
<span wicket:id="bankAccountHolderLabel">
Bank AccountHolder:
</span>
</td>
<td>
<wicket:container wicket:id="bankAccountHolderFeedback">
<input wicket:id="bankAccountHolder"/>
</wicket:container>
</td>
</tr>
</table>
</td>
</tr>
<tr><td> </td><td> </td></tr>
<tr>
<td>
<input type="radio" wicket:id="postalAccount">
<span wicket:id="postalAccountLabel">
Postal Account
</span>
</td>
<td>
<table border="0">
<tr>
<td>
<span wicket:id="postalAccountNumberLabel">
Postal Account Number:
</span>
</td>
<td>
<wicket:container wicket:id="postalAccountNumberFeedback">
<input wicket:id="postalAccountNumber"/>
</wicket:container>
</td>
</tr>
<tr>
<td>
<span wicket:id="postalAccountHolderLabel">
Postal Account Holder:
</span>
</td>
<td>
<wicket:container wicket:id="postalAccountHolderFeedback">
<input wicket:id="postalAccountHolder"/>
</wicket:container>
</td>
</tr>
</table>
</td>
</tr>
</table>
</wicket:container>
</wicket:container>
</wicket:panel>
</body>
</html>
The CSS class which is used to visualize components that caused a validation errors is defined as
.errorFeedback { background-color: #FA8895; }
If this CSS class is referred to by an HTML element, it causes the element to be shown with a red background. This CSS class is used by the presented example for showing validation errors by the feedback container. The following code snippets show how. It creates the feedback container for the feedback panel (1) in Figure 2.
// initializes the feedback container
accountsFeedbackContainer = new CSSFeedbackContainer("accountsFeedbackContainer",
"errorFeedback");
this.add(accountsFeedbackContainer);
The first argument of the constructor CSSFeedbackContainer is the id of the markup container to which the feedback panel will be bound. The second argument is the name of the CSS class that is used to visualize a feedback error.
// Set the components that will show a validation error feedback
accountsFeedbackContainer.addErrorFeedbackComponetIds(
new String[]{"bankAccountLabel", "postalAccountLabel"});
The above code adds the ids of the two labels bankAccountLabel and postalAccountLabel as components that will show validation error feedback if any of the components that are observed as source of validation error return an error.
// Set the components whose validation errors will be ignored by this component
accountsFeedbackContainer.addIgnoredComponentIds(
new String[]{"bankAddress",
"bankAccountNumber",
"bankAccountHolder",
"postalAccountNumber",
"postalAccountHolder"});
The code above excludes any validations errors caused by the components with the id bankAddress, bankAccountNumber, bankAccountHolder, postalAccountNumber, and postalAccountHolder. This is necessary, as those components are each handled by an own feedback container that is, in turn, contained in the outer feedback container.
accountsFeedbackContainer.add(accountRadioGroup);
The above code adds the radio group, which contains the radio button for the selection of either a bank or a postal account, to the feedback container. All elements of the bank account and postal account will be in turn added directly or indirectly added to the accountRadioGroup container or one of its sub-container, respectively.
The input fields of the bank account and postal account are enclosed by an own feedback container handling all validation errors that occur on their own. The following code describes how the inner feedback container for the bank account number is created.
// bank account number text field and label
bankAccountNumberLabel = new Label("bankAccountNumberLabel",
new Model("Account Number:"));
bankAccountNumber = new TextField("bankAccountNumber");
// feedback for validation errors of the bank account number
CSSFeedbackContainer bankAccountNumberFeedback =
new CSSFeedbackContainer("bankAccountNumberFeedback",
"errorFeedback");
accountRadioGroup.add(bankAccountNumberFeedback);
bankAccountNumberFeedback.add(bankAccountNumber);
bankAccountNumber.setRequired(true);
accountRadioGroup.add(bankAccountNumberLabel);
The above code simply binds the bank account number label and the corresponding bank account number text field to the corresponding elements in the Wicket-HTML. Thereafter, a new feedback container (bankAccountNumberFeedback) is created which is then added to the accountRadioGroup. The account number label and the account number text field are added to the feedback container. The code of the other parts in the Wicket UI are similar to the above code.
Hands-On
If you like to test and see in detail how it works, download the source code for the above example, including the feedback component, from here. Unzip it. Then run it with Maven 2 by entering
mvn clean jetty:run
After startup, the demo web application is reachable under
http://localhost/WicketCSSFeedback/
Conclusions
This article presented a feedback container component which allows one to
- show validation feedback for multiple components involved in an error of a form-validation.
- use a CSS class to show the feedback of a validation error.
Hi, thanks for this great article. I try to download the source code but I have the following error : Forbidden Error 403.
AntwortenLöschenHi, I had no problem to download the file with the link:
AntwortenLöschenhttps://docs.google.com/leaf?id=0B_HLXD4_Sf3pMDNkNjlkZmEtZjk5Ni00ODRmLWFjNTItNThjZDc0MWI2NmZl&hl=en
Could you please try that again?
Nice blog, very interesting to read
AntwortenLöschenI have bookmarked this article page as i received good information from this.
Best ERP Software in Hyderabad
ERP Hyderabad
ERP Software Providers in Hyderabad