├── README.md
├── pom.xml
└── src
└── main
├── java
└── com
│ └── thymeleafexamples
│ └── select
│ ├── config
│ ├── SpringWebInitializer.java
│ └── WebMvcConfig.java
│ ├── dao
│ ├── HobbyDao.java
│ └── UserDao.java
│ ├── domain
│ ├── Hobby.java
│ └── User.java
│ └── web
│ ├── HobbyFormatter.java
│ └── IndexController.java
└── webapp
└── WEB-INF
├── templates
├── editCheckbox.html
├── editSelect.html
└── index.html
└── web.xml
/README.md:
--------------------------------------------------------------------------------
1 | thymeleafexamples-selectmultiple
2 | ================================
3 |
4 | Example application to illustrate one forum question (problem with select multiple).
5 |
6 | This example uses:
7 | * Spring 4 with Java config
8 | * Thymeleaf 2.1
9 | * Spring conversion service
10 |
11 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.thymeleafexamples
6 | select
7 | 1.0-SNAPSHOT
8 | war
9 |
10 | Thymeleaf select multiple example
11 |
12 |
13 | UTF-8
14 | UTF-8
15 | 2.1.2.RELEASE
16 | 4.0.2.RELEASE
17 | 1.7
18 | 1.7
19 |
20 |
21 |
22 |
23 |
24 | javax
25 | javaee-web-api
26 | 7.0
27 | provided
28 |
29 |
30 |
31 | org.springframework
32 | spring-context-support
33 | ${spring.version}
34 |
35 |
36 | org.springframework
37 | spring-webmvc
38 | ${spring.version}
39 |
40 |
41 | org.thymeleaf
42 | thymeleaf
43 | ${thymeleaf.version}
44 |
45 |
46 | org.thymeleaf
47 | thymeleaf-spring4
48 | ${thymeleaf.version}
49 |
50 |
51 |
52 |
53 | select
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/main/java/com/thymeleafexamples/select/config/SpringWebInitializer.java:
--------------------------------------------------------------------------------
1 | package com.thymeleafexamples.select.config;
2 |
3 | import javax.servlet.ServletContext;
4 | import javax.servlet.ServletException;
5 | import javax.servlet.ServletRegistration.Dynamic;
6 | import org.springframework.web.WebApplicationInitializer;
7 | import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
8 | import org.springframework.web.servlet.DispatcherServlet;
9 |
10 | /**
11 | * Spring configuration and Spring MVC bootstrapping.
12 | */
13 | public class SpringWebInitializer implements WebApplicationInitializer {
14 |
15 | @Override
16 | public void onStartup(ServletContext servletContext) throws ServletException {
17 | AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
18 | context.register(WebMvcConfig.class);
19 | context.setServletContext(servletContext);
20 | // Spring MVC front controller
21 | Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(context));
22 | servlet.addMapping("/");
23 | servlet.setLoadOnStartup(1);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/thymeleafexamples/select/config/WebMvcConfig.java:
--------------------------------------------------------------------------------
1 | package com.thymeleafexamples.select.config;
2 |
3 | import com.thymeleafexamples.select.web.HobbyFormatter;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.ComponentScan;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.format.FormatterRegistry;
8 | import org.springframework.web.servlet.config.annotation.EnableWebMvc;
9 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
10 | import org.thymeleaf.spring4.SpringTemplateEngine;
11 | import org.thymeleaf.spring4.view.ThymeleafViewResolver;
12 | import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
13 |
14 | /**
15 | * Spring MVC configuration.
16 | */
17 | @Configuration
18 | @EnableWebMvc
19 | @ComponentScan("com.thymeleafexamples.select")
20 | public class WebMvcConfig extends WebMvcConfigurerAdapter {
21 |
22 | private static final String ENCODING = "UTF-8";
23 |
24 | @Bean
25 | public ServletContextTemplateResolver templateResolver() {
26 | ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
27 | resolver.setPrefix("/WEB-INF/templates/");
28 | resolver.setSuffix(".html");
29 | resolver.setTemplateMode("HTML5");
30 | resolver.setCacheable(false);
31 | return resolver;
32 | }
33 |
34 | @Bean
35 | public SpringTemplateEngine templateEngine() {
36 | SpringTemplateEngine engine = new SpringTemplateEngine();
37 | engine.setTemplateResolver(templateResolver());
38 | return engine;
39 | }
40 |
41 | @Bean
42 | public ThymeleafViewResolver thymeleafViewResolver() {
43 | ThymeleafViewResolver resolver = new ThymeleafViewResolver();
44 | resolver.setCharacterEncoding(ENCODING);
45 | resolver.setTemplateEngine(templateEngine());
46 | return resolver;
47 | }
48 |
49 | @Override
50 | public void addFormatters(FormatterRegistry formatterRegistry) {
51 | formatterRegistry.addFormatter(new HobbyFormatter());
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/thymeleafexamples/select/dao/HobbyDao.java:
--------------------------------------------------------------------------------
1 | package com.thymeleafexamples.select.dao;
2 |
3 | import com.thymeleafexamples.select.domain.Hobby;
4 | import java.util.Collection;
5 | import java.util.HashMap;
6 | import org.springframework.stereotype.Service;
7 |
8 | @Service
9 | public class HobbyDao {
10 |
11 | private HashMap ALL_HOBBIES = new HashMap(){{
12 | put("CNM", new Hobby("CNM", "Cinema"));
13 | put("FTB", new Hobby("FTB", "Football"));
14 | put("PAI", new Hobby("PAI", "Painting"));
15 | put("PKR", new Hobby("PKR", "Poker"));
16 | put("DRT", new Hobby("DRT", "Darts"));
17 | put("POL", new Hobby("POL", "Pool"));
18 | put("SWI", new Hobby("SWI", "Swimming"));
19 | put("OPR", new Hobby("OPR", "Opera"));
20 | }};
21 |
22 | public Collection findAll() {
23 | return ALL_HOBBIES.values();
24 | }
25 |
26 | public Hobby findOne(String id) {
27 | return ALL_HOBBIES.get(id);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/thymeleafexamples/select/dao/UserDao.java:
--------------------------------------------------------------------------------
1 | package com.thymeleafexamples.select.dao;
2 |
3 | import com.thymeleafexamples.select.domain.Hobby;
4 | import com.thymeleafexamples.select.domain.User;
5 | import java.util.ArrayList;
6 | import java.util.List;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.stereotype.Service;
9 |
10 | @Service
11 | public class UserDao {
12 |
13 | @Autowired HobbyDao hobbyDao;
14 |
15 | private final List DEFAULT_HOBBIES = new ArrayList(){{
16 | add(new Hobby("CNM", "Cinema"));
17 | add(new Hobby("PKR", "Poker"));
18 | add(new Hobby("SWI", "Swimming"));
19 | }};
20 |
21 | private final User MEMORY_USER = new User("USR101", DEFAULT_HOBBIES);
22 |
23 | public User findOne() {
24 | return MEMORY_USER;
25 | }
26 |
27 | public void save(User user) {
28 | List newHobbies = new ArrayList<>();
29 | if (user.getHobbies() != null) {
30 | for (Hobby hobby : user.getHobbies()) {
31 | newHobbies.add(hobbyDao.findOne(hobby.getId()));
32 | }
33 | }
34 | MEMORY_USER.setHobbies(newHobbies);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/thymeleafexamples/select/domain/Hobby.java:
--------------------------------------------------------------------------------
1 | package com.thymeleafexamples.select.domain;
2 |
3 | import java.util.Objects;
4 |
5 | public class Hobby {
6 |
7 | private String id;
8 |
9 | private String description;
10 |
11 | public Hobby() {
12 | }
13 |
14 | public Hobby(String id, String description) {
15 | this.id = id;
16 | this.description = description;
17 | }
18 |
19 | public String getId() {
20 | return id;
21 | }
22 |
23 | public void setId(String id) {
24 | this.id = id;
25 | }
26 |
27 | public String getDescription() {
28 | return description;
29 | }
30 |
31 | @Override
32 | public int hashCode() {
33 | int hash = 5;
34 | hash = 83 * hash + Objects.hashCode(this.id);
35 | return hash;
36 | }
37 |
38 | @Override
39 | public boolean equals(Object obj) {
40 | if (obj == null) {
41 | return false;
42 | }
43 | if (getClass() != obj.getClass()) {
44 | return false;
45 | }
46 | final Hobby other = (Hobby) obj;
47 | if (!Objects.equals(this.id, other.id)) {
48 | return false;
49 | }
50 | return true;
51 | }
52 |
53 | public void setDescription(String description) {
54 | this.description = description;
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/src/main/java/com/thymeleafexamples/select/domain/User.java:
--------------------------------------------------------------------------------
1 | package com.thymeleafexamples.select.domain;
2 |
3 | import java.util.List;
4 |
5 | public class User {
6 |
7 | private String id;
8 |
9 | private List hobbies;
10 |
11 | public User() {
12 | }
13 |
14 | public User(String id, List hobbies) {
15 | this.id = id;
16 | this.hobbies = hobbies;
17 | }
18 |
19 | public String getId() {
20 | return id;
21 | }
22 |
23 | public void setId(String id) {
24 | this.id = id;
25 | }
26 |
27 | public List getHobbies() {
28 | return hobbies;
29 | }
30 |
31 | public void setHobbies(List hobbies) {
32 | this.hobbies = hobbies;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/thymeleafexamples/select/web/HobbyFormatter.java:
--------------------------------------------------------------------------------
1 | package com.thymeleafexamples.select.web;
2 |
3 | import com.thymeleafexamples.select.domain.Hobby;
4 | import java.text.ParseException;
5 | import java.util.Locale;
6 | import org.springframework.format.Formatter;
7 |
8 | public class HobbyFormatter implements Formatter {
9 |
10 | @Override
11 | public String print(Hobby hobby, Locale locale) {
12 | return hobby.getId();
13 | }
14 |
15 | @Override
16 | public Hobby parse(String id, Locale locale) throws ParseException {
17 | Hobby hobby = new Hobby();
18 | hobby.setId(id);
19 | return hobby;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/thymeleafexamples/select/web/IndexController.java:
--------------------------------------------------------------------------------
1 | package com.thymeleafexamples.select.web;
2 |
3 | import com.thymeleafexamples.select.dao.HobbyDao;
4 | import com.thymeleafexamples.select.dao.UserDao;
5 | import com.thymeleafexamples.select.domain.User;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Controller;
8 | import org.springframework.ui.Model;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.bind.annotation.RequestMethod;
11 |
12 | @Controller
13 | public class IndexController {
14 |
15 | @Autowired UserDao userDao;
16 | @Autowired HobbyDao hobbyDao;
17 |
18 | @RequestMapping(value = "/", method = RequestMethod.GET)
19 | public String index(Model model) {
20 | model.addAttribute("user", userDao.findOne());
21 | return "index";
22 | }
23 |
24 | @RequestMapping(value = "/editSelect", method = RequestMethod.GET)
25 | public String editSelect(Model model) {
26 | model.addAttribute("user", userDao.findOne());
27 | model.addAttribute("allHobbies", hobbyDao.findAll());
28 | return "editSelect";
29 | }
30 |
31 | @RequestMapping(value = "/editCheckbox", method = RequestMethod.GET)
32 | public String editCheckbox(Model model) {
33 | model.addAttribute("user", userDao.findOne());
34 | model.addAttribute("allHobbies", hobbyDao.findAll());
35 | return "editCheckbox";
36 | }
37 |
38 | @RequestMapping(value = "/save", method = RequestMethod.POST)
39 | public String save(User user) {
40 | userDao.save(user);
41 | return "redirect:/";
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/templates/editCheckbox.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Edit user hobbies
5 |
6 |
7 | Edit user hobbies
8 |
18 |
19 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/templates/editSelect.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Edit user hobbies
5 |
6 |
7 | Edit user hobbies
8 |
22 |
23 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | User hobbies
5 |
6 |
7 | User hobbies
8 |
9 | -
11 | Cinema
12 |
13 |
14 | Edit user hobbies with a multiple select
15 | Edit user hobbies with checkboxes
16 |
17 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------