Last Updated on 30 April 2020   |   Print Email
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: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:In Java code, we create the entity class Useras 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:
Then when in create new mode, it will show checkboxes with label corresponding to role names in the database: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: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.
Nam Ha Minh 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.
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!
Comments
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....
You could make your tutorial complete by including that part.
Otherwise a nice tutorial!
Do not use DTO in this case. DTO should be use for transferring data from RESTful webservices to client (browser).