Enterprise Java

Spring MVC: form handling vol. 2 – checkbox processing


It’s hard to imagine a situation when a modern web-application doesn’t have checkboxes in a form. In one of the previous posts I wrote about form handling in Spring MVC, as a continuation of this series I’m going to write about Spring MVC forms, and in particular about checkbox processing. This post will be about a standard usage of tag.
 
 
I’ll examine three cases of the checkbox tag usage, when:

  • Chekbox is a boolean value
  • Chekbox is a string value
  • Group of checkboxes represents an array of strings

So you can see that these three points are simple enough, but they need some attention from developer’s side. Below I will describe how to realize each of these cases, you can download the source code in the end of the article.

Checkbox: boolean

For the first case I will use the following domain model:

public class Hobby {

	private boolean hobbyExists;

	public boolean isHobbyExists() {
		return hobbyExists;
	}

	public void setHobbyExists(boolean hobbyExists) {
		this.hobbyExists = hobbyExists;
	}

}

This class doesn’t need any explanations, because it’s simple bean with getters and setters. Now I can show you views for this case:

<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
...
<h1>Hobby page</h1>
<form:form method="POST" commandname="hobby" action="hobby-result.html">
<table>
    <tbody><tr>
        <td>Is any hobby: </td>
        <td><form:checkbox path="hobbyExists"></form:checkbox></td>
    </tr>
    <tr>
        <td colspan="2">
            <input value="Submit" type="submit">
        </td>
    </tr>
</tbody></table>  
</form:form>
...

Notice that usage of Spring form tag implies import of the appropriate tag library. The checkbox tag contains the attribute path which corresponds to the property of the domain model. The result will be displayed on another page:

...
<h1>Hobby result page</h1>
Is any hobby? - ${hobby.hobbyExists} <br />
...

And finally I need to declare a controller for all this stuff:

@Controller
public class HobbyController {

	@RequestMapping(value="/hobby-page")
	public ModelAndView hobbyFormPage() {
		return new ModelAndView("hobby-form", "hobby", new Hobby());
	}

	@RequestMapping(value="/hobby-result")
	public ModelAndView processHobby(@ModelAttribute Hobby hobby) {
		ModelAndView modelAndView = new ModelAndView("hobby-result");
		modelAndView.addObject("hobby", hobby);
		return modelAndView;
	}

}

Checkbox: string

The second case will be explained with the following domain model:

public class JobOffer {

	private String parking;

	public String getParking() {
		return parking;
	}

	public void setParking(String parking) {
		this.parking = parking;
	}

}

The view for this situation will be a little bit different from the previous one:

...
<h1>Job Offer page</h1>

<form:form method="POST" commandname="job" action="job-result.html">

 <table>

  <tbody>
   <tr>

    <td>Job with parking? - </td>

    <td>
     <form:checkbox path="parking" value="parking" /></td>

   </tr>

   <tr>

    <td colspan="2">
            <input type="submit" value="Submit" />
        </td>

   </tr>

  </tbody>
 </table>  

</form:form>
...

Notice that a new attribute appears in the checkbox tag. The value attribute represents the string property from the domain model.
The result will be displayed on another page:

...
	<h1>Job result page</h1>

<c:choose>

 <c:when test="${job.parking != null}">
  You want job with ${job.parking}
 </c:when>

 <c:otherwise>
  You want job without parking
 </c:otherwise>

</c:choose>
...

And the controller for this example:

@Controller
public class JobController {

	@RequestMapping(value="/job-page")
	public ModelAndView jobOfferPage() {		
		return new ModelAndView("job-form", "job", new JobOffer());
	}

	@RequestMapping(value="/job-result")
	public ModelAndView processJob(@ModelAttribute JobOffer jobOffer) {
		ModelAndView modelAndView = new ModelAndView("job-result");
		modelAndView.addObject("job", jobOffer);
		return modelAndView;
	}
}

Checkbox: string array

The last case of the tutorial will describe how to bind an array of strings to a property from a domain model. In the same way you can bind values of java.util.Collection. So the domain model will look like this:

public class Food {

	private String[] favoriteFruit;

	public String[] getFavoriteFruit() {
		return favoriteFruit;
	}

	public void setFavoriteFruit(String[] favoriteFruit) {
		this.favoriteFruit = favoriteFruit;
	}
}

The page with the form:

...
<h1>Fruit page</h1>

<form:form method="POST" commandname="food" action="food-result.html">

 <table>

  <tbody>
   <tr>

    <td>Apple </td>

    <td>
     <form:checkbox path="favoriteFruit" value="apple" /></td>

   </tr>

   <tr>

    <td>Orange </td>

    <td>
     <form:checkbox path="favoriteFruit" value="orange" /></td>

   </tr>

   <tr>

    <td>Banana </td>

    <td>
     <form:checkbox path="favoriteFruit" value="banana" /></td>

   </tr>

   <tr>

    <td colspan="2">
            <input type="submit" value="Submit" />
        </td>

   </tr>

  </tbody>
 </table>  

</form:form>
...

The values from the checkbox tags will be passed to the string array during the processing.
The result page:

...
<h1>Food result page</h1>
You prefer:
<br />

<c:foreach var="fruit" items="${food.favoriteFruit}">

	${fruit}
 <br />

</c:foreach>
...

And the controller for the last case:

@Controller
public class FoodController {

	@RequestMapping(value="/food-page")
	public ModelAndView foodPage() {		
		return new ModelAndView("food-form", "food", new Food());
	}

	@RequestMapping(value="/food-result")
	public ModelAndView processFuits(@ModelAttribute Food food) {
		ModelAndView modelAndView = new ModelAndView("food-result");
		modelAndView.addObject("food", food);
		return modelAndView;
	}

}

Checkbox tag feature

When some page with form is rendered, you can open its source code, and see something like this:

...
<input id="favoriteFruit1" name="favoriteFruit" type="checkbox" value="apple" />
<input type="hidden" name="_favoriteFruit" value="on" />
...

Strange, where does the additional input appear from? Official documentation explains this fact:

When a checkbox in an HTML page is not checked, its value will not be sent to the server as part of the HTTP request parameters once the form is submitted, so we need a workaround for this quirk in HTML in order for Spring form data binding to work. The checkbox tag follows the existing Spring convention of including a hidden parameter prefixed by an underscore (“_”) for each checkbox. By doing this, you are effectively telling Spring that “ the checkbox was visible in the form and I want my object to which the form data will be bound to reflect the state of the checkbox no matter what ”.

Summary

This article gives you a high level overview of the checkbox tag usage, but this is just a base. In the nearest posts I will show you more interesting situations of the checkbox usage in Spring MVC. You can download the source code of the entire application clicking on the link.
 

Alexey Zvolinskiy

Alexey is a test developer with solid experience in automation of web-applications using Java, TestNG and Selenium. He is so much into QA that even after work he provides training courses for junior QA engineers.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Pravalya
Pravalya
10 years ago

Can u please help me with this problem:

The problem is that, in springs pagination,the result is not displayed automatically when i clisk on next button, but i have to click the submit button before the new results are shown.

And as i see it, it must be because the form is not submitted, when i click on the link.

How can i solve this in a Spring way, so that i dont have to click on the submit button again before the search results are displayed ?

And yes i am new to Spring

Best Regards
pravalya

Back to top button