In this quick post, I will share with you some code examples to display multiple checkboxes in HTML form with Spring MVC and Thymeleaf. The values of the checkboxes are mapped with a collection which is a field of a model class. For example, you want to code the user form that looks like this:

spring thymeleaf form multi checkboxes

A user can have one or more (multiple) roles, so the Roles field in this form is represented with multiple checkboxes corresponding to role names in the database.

In the database, we have 3 tables to implement many-to-many relationship between users and roles as follows:

users and roles relationship

In Java code, we create the entity class User as follows (I show only the relevant code in the context of this post):

package net.codejava

import java.util.*;
import javax.persistence.*

@Entity
@Table(name = "users")
public class User {
	
	
	@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
	@JoinTable(
			name = "users_roles",
			joinColumns = @JoinColumn(name = "user_id"),
			inverseJoinColumns = @JoinColumn(name = "role_id")
			)
	private Set<Role> roles = new HashSet<>();
	
}

You see, the User class has a Set of Roles. You should override toString(), equals() and hashCode() in the Role class as follows:

package net.codejava;

import javax.persistence.*;

@Entity
@Table(name = "roles")
public class Role {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;
	private String name;

	// getters and setters are not shown
	
	@Override
	public String toString() {
		return this.name;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Role other = (Role) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}	
}

We need to override toString() method so role names will be shown in the form. And equals() and hashCode() must be overridden so Spring MVC and Thymeleaf will show the check marks correctly when the form is in edit mode.

For Spring Data JPA repository interfaces, i.e. UserRepository and RoleRepository – nothing special. We don’t have to write any extra code.

And in the Spring MVC controller class, we need to code the handlers for create new user and edit existing user as follows:

package net.codejava;

@Controller
public class UserController {

	@Autowired
	private UserServices service;
	
	@Autowired 
	private RoleRepository roleRepository;
	
	@GetMapping("/users/new")
	public ModelAndView newUser() {
		User user = new User();
		ModelAndView mav = new ModelAndView("user_form");
		mav.addObject("user", user);
		
		List<Role> roles = (List<Role>) roleRepository.findAll();
		
		mav.addObject("allRoles", roles);
		
		return mav;		
	}	
	
	@GetMapping("/users/edit/{id}")
	public ModelAndView editUser(@PathVariable(name = "id") Integer id) {
		User user = service.get(id);
		ModelAndView mav = new ModelAndView("user_form");
		mav.addObject("user", user);
		
		List<Role> roles = (List<Role>) roleRepository.findAll();
		
		mav.addObject("allRoles", roles);
		
		return mav;
	}	
}

The key point here is to add a collection of Role objects to the model:

List<Role> roles = (List<Role>) roleRepository.findAll();
mav.addObject("allRoles", roles);

And in the view with Thymeleaf, write code for displaying the checkboxes like this:

<form th:action="@{/users/save}" th:object="${user}" method="post">
<p>
	<label>Roles: 
		<input type="checkbox" name="roles"
			th:each="role : ${allRoles}" 
			th:text="${role.name}"
			th:value="${role.id}"
			th:field="*{roles}"
		/>
	</label>
</p>
</form>

Then when in create new mode, it will show checkboxes with label corresponding to role names in the database:

spring thymeleaf form multi checkboxes

We don’t have to write any special code for the save user handler method, as Spring MVC, Thymeleaf and Spring Data JPA do an excellent job to automatically persist the User object and associate Role objects.

In edit mode, it will show the check marks correctly according to the association between user and roles, for example:

spring thymeleaf form multi checkboxes edit

That’s some code example of how to use Spring and Thymeleaf to easily display multi-checkboxes on a HTML form mapping with values in database nicely. I hope you found this post helpful.

 

Other Spring Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Add comment

   


Comments 

#25Ali2023-03-01 07:41
Hi,

Great example which works fine with ManyToMany

What about OneToMany/ManyToOne Please ?
I tried to change checkbox to input text and it does not work for onetomany/manytoone....
Quote
#24Joe2022-11-22 10:12
Perfect brother. This works flawlessly and solved my problem. Thanks so much ????
Quote
#23Kian2021-12-09 12:41
You omit the most important part, how to recieve the data in the controller when the form is submitted. It is no use the have the data printed; just saying "We don’t have to write any special code for the save user handler method" doesn't help someone who does not know how to do it.
You could make your tutorial complete by including that part.
Otherwise a nice tutorial!
Quote
#22Vinh2021-09-23 08:43
Thank you very much!
Quote
#21Nam2021-09-21 17:05
Hi Vinh,
Do not use DTO in this case. DTO should be use for transferring data from RESTful webservices to client (browser).
Quote