4.1.7checkboxes标签

4.1.7 checkboxes标签

渲染成多个多框

Spring MVCcheckboxes标签会渲染多个类型为checkbox的普通HTML input标签。

属性

checkboxes标签可使用如表4.8所示的属性。表4.8中列出的只是SpringMVCcheckboxes标签的常用属性,并没有包含HTML的相关属性。

属性 描述
cssClass 定义要应用到被渲染的checkbox元素的CSS
cssStyle 定义要应用到被渲染的checkbox元素的CSS样式
cssErrorClass 定义要应用到被渲染的checkbox元素的CSS类,如果bound属性中宝行错误,则覆盖cssClass属性值
htmlEscape boolean值,表示被渲染的值是否应该进行HTML转义
path 要绑定的属性的路径
items 用于生成checkbox元素的对象的Collection,Map或者Array
itemLabel item属性中定义的Collection,Map或者Array中对象的属性,为每个checkbox元素提供label
itemValue item属性中定义的Collection,Map或者Array中的对象属性,为每个checkbox元素提供值
delimiter 定义两个input元素之间的分割符,默认没有分割符

优点:可生成多个复选框

相对于一个checkbox标签只能生成一个对应的复选框而言,一个checkboxes标签将根据其绑定的数据生成多个复选框。

可绑定的数据类型

checkboxes绑定的数据可以是数组集合Map

必须属性 path items

在使用checkboxes标签时有两个属性是必须指定的,一个是path,另一个是items

  • items表示当前要用来显示的项有哪些,
  • path所绑定的表单对象的属性表示当前表单对象拥有的项,即在items所显示的所有项中表单对象拥有的项会被设定为选中状态。

示例:checkboxes标签的使用

项目结构

展开/折叠
G:\Desktop\随书源码\Spring+Mybatis企业应用实战(第2版)\codes\04\CheckboxesTest
├─src\
│ └─org\
│   └─fkit\
│     ├─controller\
│     │ └─UserController.java
│     └─domain\
│       ├─Dept.java
│       ├─Employee.java
│       └─User.java
└─WebContent\
  ├─index.jsp
  ├─META-INF\
  │ └─MANIFEST.MF
  └─WEB-INF\
    ├─content\
    │ ├─checkboxesForm.jsp
    │ ├─checkboxesForm2.jsp
    │ └─checkboxesForm3.jsp
    ├─lib\
    │ ├─commons-logging-1.2.jar
    │ ├─spring-aop-5.0.1.RELEASE.jar
    │ ├─spring-aspects-5.0.1.RELEASE.jar
    │ ├─spring-beans-5.0.1.RELEASE.jar
    │ ├─spring-context-5.0.1.RELEASE.jar
    │ ├─spring-context-indexer-5.0.1.RELEASE.jar
    │ ├─spring-context-support-5.0.1.RELEASE.jar
    │ ├─spring-core-5.0.1.RELEASE.jar
    │ ├─spring-expression-5.0.1.RELEASE.jar
    │ ├─spring-instrument-5.0.1.RELEASE.jar
    │ ├─spring-jcl-5.0.1.RELEASE.jar
    │ ├─spring-jdbc-5.0.1.RELEASE.jar
    │ ├─spring-jms-5.0.1.RELEASE.jar
    │ ├─spring-messaging-5.0.1.RELEASE.jar
    │ ├─spring-orm-5.0.1.RELEASE.jar
    │ ├─spring-oxm-5.0.1.RELEASE.jar
    │ ├─spring-test-5.0.1.RELEASE.jar
    │ ├─spring-tx-5.0.1.RELEASE.jar
    │ ├─spring-web-5.0.1.RELEASE.jar
    │ ├─spring-webflux-5.0.1.RELEASE.jar
    │ ├─spring-webmvc-5.0.1.RELEASE.jar
    │ └─spring-websocket-5.0.1.RELEASE.jar
    ├─springmvc-config.xml
    └─web.xml

使用数组 List Set作为数据源

User.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package org.fkit.domain;

import java.io.Serializable;
import java.util.List;

// 域对象,实现序列化接口
public class User
implements Serializable
{

private static final long serialVersionUID = 1L;
// 课程列表
private List<String> courses;

public User()
{
super();
}

public List<String> getCourses()
{
return courses;
}

public void setCourses(List<String> courses)
{
this.courses = courses;
}
}

UserController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package org.fkit.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.fkit.domain.Dept;
import org.fkit.domain.Employee;
import org.fkit.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class UserController {

@GetMapping(value = "/checkboxesForm")
public String registerForm(Model model)
{
User user = new User();
// 为集合变量courses添加“JAVAEE”和“Spring”,页面的checkbox复选框这两项会被选中
List<String> list = new ArrayList<String>();
list.add("JAVAEE");
list.add("Spring");
user.setCourses(list);
// 页面展现的可供选择的复选框内容courseList
List<String> courseList = new ArrayList<String>();
courseList.add("JAVAEE");
courseList.add("Mybatis");
courseList.add("Spring");
// model中添加属性user和courseList
model.addAttribute("user", user);
model.addAttribute("courseList", courseList);
// 返回视图的路径
return "checkboxesForm";
}
@GetMapping(value = "/checkboxesForm2")
public String registerForm2(Model model)
{
User user = new User();
// 为集合变量courses添加“JAVAEE”和“Spring”,页面的checkbox复选框这两项会被选中
List<String> list = new ArrayList<String>();
list.add("1");
list.add("3");
user.setCourses(list);
// 页面展现的可供选择的复选框内容courseList
Map<String, String> courseMap = new HashMap<String, String>();
courseMap.put("1", "JAVAEE");
courseMap.put("2", "Mybatis");
courseMap.put("3", "Spring");
// model中添加属性user和courseList
model.addAttribute("user", user);
model.addAttribute("courseMap", courseMap);
// 返回视图的路径
return "checkboxesForm2";
}

@GetMapping(value = "/checkboxesForm3")
public String registerForm3(Model model)
{
Employee employee = new Employee();
Dept dept = new Dept(1, "开发部");
// 为集合变量depts添加Dept对象,该对象id=1,name=开发吧,页面的checkbox复选框这一项会被选中
List<Dept> list = new ArrayList<Dept>();
list.add(dept);
employee.setDepts(list);
// 页面展现的可供选择的复选框内容deptList
List<Dept> deptList = new ArrayList<Dept>();
deptList.add(dept);
deptList.add(new Dept(2, "销售部"));
deptList.add(new Dept(3, "财务部"));
// model中添加属性employee和deptList
model.addAttribute("employee", employee);
model.addAttribute("deptList", deptList);
// 返回视图路径
return "checkboxesForm3";
}

}

UserController类中创建User对象, 并给User对象的courses集合变量添加了“JAVAEE” 和“Spring” 课程。 之后创建了courseList集合变量, 该集合变量的内容作为页面显示的可供选择的复选框内容。 而页面显示的内容如果在courses中存在, 则会被设置为选中状态, 即“JAVAEE” 和“Spring” 内容会默认被选中。

checkboxesForm.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试checkboxes标签</title>
</head>
<body>
<h3>form:checkboxes测试</h3>
<!-- modelAttribute="user" 表示当前表单绑定的是model中的user属性 -->
<form:form modelAttribute="user" method="post" action="checkboxesForm">
<table>
<tr>
<td>选择课程:</td>
<!-- items="${courseList}" 表示复选框的 选项列表 是 model中courseList的内容 -->
<!-- path="courses" 表示复选框 勾选的选项 是 表单绑定的user对象的courses成员变量中的内容 -->
<td><form:checkboxes items="${courseList}" path="courses"
delimiter="<br>" /></td>
<!-- delimiter="<br>" 表示每个列表项用换行分隔 -->
</tr>
</table>
</form:form>
</body>
</html>

web.xml文件和springmvc-config.xml文件与之前讲述的一致, 此处不再赘述。

测试

部署CheckboxesTest这个Web应用, 在浏览器中输入如下URL来测试应用:

http://localhost:8080/CheckboxesTest/checkboxesForm

渲染效果

html代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<form id="user" action="checkboxesForm" method="post">
<table>
<tr>
<td>选择课程:</td>
<td><span>
<input id="courses1" name="courses" type="checkbox" value="JAVAEE" checked="checked" />
<label for="courses1">JAVAEE</label>
</span>
<span>
<br>
<input id="courses2" name="courses" type="checkbox" value="Mybatis" />
<label for="courses2">Mybatis</label>
</span>
<span>
<br>
<input id="courses3" name="courses" type="checkbox" value="Spring" checked="checked" />
<label for="courses3">Spring</label>
</span>
<input type="hidden" name="_courses" value="on" />
</td>
</tr>
</table>
</form>

显示效果

展开/折叠
选择课程:

上面介绍的情况是使用List集合作为显示复选框项的数据源, 我们可以看到, 复选框所呈现出来的标签label和该复选框的值是一样的。 使用ArraySet作为数据源也是这样。

<span>
    <input id="courses1" name="courses" type="checkbox" value="JAVAEE" checked="checked" />
    <label for="courses1">JAVAEE</label>
</span>

使用Map作为数据源

那么如果要让checkboxes呈现出来的labelvalue不同应该怎么做呢? 这时我们可以使用Map作为数据源。 使用Map作为checkboxesitems属性的数据源时,Map集合的key将作为真正的复选框的value, 而Map集合的value将作为label进行显示。 当使用Map作为checkboxesitems属性的数据源时我们绑定的表单对象属性的类型可以是Array、 集合和Map, 这种情况下就是判断items Map中是否含有对应的key来决定当前的复选框是否处于选中状态。

请求处理方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@GetMapping(value = "/checkboxesForm2")
public String registerForm2(Model model)
{
User user = new User();
// 为集合变量courses添加“JAVAEE”和“Spring”,页面的checkbox复选框这两项会被选中
List<String> list = new ArrayList<String>();
list.add("1");
list.add("3");
user.setCourses(list);
// 页面展现的可供选择的复选框内容courseList
Map<String, String> courseMap = new HashMap<String, String>();
courseMap.put("1", "JAVAEE");
courseMap.put("2", "Mybatis");
courseMap.put("3", "Spring");
// model中添加属性user和courseList
model.addAttribute("user", user);
model.addAttribute("courseMap", courseMap);
// 返回视图的路径
return "checkboxesForm2";
}

registerForm2方法中, 提供给页面显示的可供选择的复选框列表内容courseMap是一个Map, 而user对象的courses集合变量中保存的正是courseMap中的key, 它用来决定页面的复选框是否处于选中状态。

测试

在浏览器中输入如下URL来测试应用:

http://localhost:8080/CheckboxesTest/checkboxesForm2

渲染效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<form id="user" action="checkboxesForm2" method="post">
<table>
<tr>
<td>选择课程:</td>
<td>
<span>
<input id="courses1" name="courses" type="checkbox" value="1" checked="checked" />
<label for="courses1">JAVAEE</label>
</span>
<span>
<br>
<input id="courses2" name="courses" type="checkbox" value="2" />
<label for="courses2">Mybatis</label>
</span>
<span>
<br>
<input id="courses3" name="courses" type="checkbox" value="3" checked="checked" />
<label for="courses3">Spring</label>
</span>
<input type="hidden" name="_courses" value="on" />
</td>
</tr>
</table>
</form>

查看源代码, 发现checkboxvaluelabel不同了,value的值正是Mapkey, 而label的值正是Mapvalue

<span>
    <input id="courses1" name="courses" type="checkbox" value="1" checked="checked" />
    <label for="courses1">JAVAEE</label>
</span>

渲染效果

选择课程:

itemLabel和itemValue属性

当使用Array或者集合作为数据源, 且里面的元素都是一个domain对象时, 还可以使用checkboxes标签的itemLabelitemValue属性来表示, 使用数组或者集合中元素对象的哪一个属性作为需要呈现的单选框的labelvalue

Dept.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package org.fkit.domain;
import java.io.Serializable;
public class Dept
implements Serializable
{
private static final long serialVersionUID = 1L;
// 编号
private Integer id;
// 姓名
private String name;
public Dept()
{
super();
// TODO Auto-generated constructor stub
}
public Dept(Integer id, String name)
{
super();
this.id = id;
this.name = name;
}
// 此处省略getter和setter方法,请自己补上
}

Dept类表示一个部门, 有idname两个属性。 之后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package org.fkit.domain;
import java.io.Serializable;
import java.util.List;
public class Employee
implements Serializable
{
private static final long serialVersionUID = 1L;
// 部门列表
private List<Dept> depts;
public List<Dept> getDepts()
{
return depts;
}
public void setDepts(List<Dept> depts)
{
this.depts = depts;
}

Employee.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package org.fkit.domain;

import java.io.Serializable;
import java.util.List;

public class Employee
implements Serializable
{

private static final long serialVersionUID = 1L;
// 部门列表
private List<Dept> depts;

public List<Dept> getDepts()
{
return depts;
}

public void setDepts(List<Dept> depts)
{
this.depts = depts;
}

}

Employee类提供了一个List集合属性depts, 用于绑定数据

checkboxesForm3.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试checkboxes标签</title>
</head>
<body>
<h3>form:checkboxes测试</h3>
<%-- 绑定到model中的employee属性(Employee对象) --%>
<form:form modelAttribute="employee" method="post"
action="checkboxesForm3">
<table>
<tr>
<td>选择部门:</td>
<td>
<%-- items中存放的是所有的选项列表 --%>
<%-- path表示要勾选上的选项 --%>
<%-- itemLabel="name" 使用employee的name属性作为label --%>
<%-- itemValue="id" 使用employee对象的id属性作为input标签的value值 --%>
<form:checkboxes items="${deptList}" path="depts"
itemLabel="name" itemValue="id" />
</td>
</tr>
</table>
</form:form>
</body>
</html>

请求处理方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@GetMapping(value = "/checkboxesForm3")
public String registerForm3(Model model)
{
Employee employee = new Employee();
Dept dept = new Dept(1, "开发部");
// 为集合变量depts添加Dept对象,该对象id=1,name=开发吧,页面的checkbox复选框这一项会被选中
List<Dept> list = new ArrayList<Dept>();
list.add(dept);
employee.setDepts(list);
// 页面展现的可供选择的复选框内容deptList
List<Dept> deptList = new ArrayList<Dept>();
deptList.add(dept);
deptList.add(new Dept(2, "销售部"));
deptList.add(new Dept(3, "财务部"));
// model中添加属性employee和deptList
model.addAttribute("employee", employee);
model.addAttribute("deptList", deptList);
// 返回视图路径
return "checkboxesForm3";
}

测试

在浏览器中输入如下URL来测试应用:

http://localhost:8080/CheckboxesTest/checkboxesForm3

渲染效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<form id="employee" action="checkboxesForm3" method="post">
<table>
<tr>
<td>选择部门:</td>
<td>
<span>
<input id="depts1" name="depts" type="checkbox" value="1" checked="checked" />
<label for="depts1">开发部</label>
</span>
<span>
<input id="depts2" name="depts" type="checkbox" value="2" />
<label for="depts2">销售部</label>
</span>
<span>
<input id="depts3" name="depts" type="checkbox" value="3" />
<label for="depts3">财务部</label>
</span>
<input type="hidden" name="_depts" value="on" />
</td>
</tr>
</table>
</form>
选择部门:

分析

可以看到, 从集合中传出来的Dept对象的name作为label显示,id作为value显示:

//Dept dept = new Dept(1, "开发部");
<span>
    <input id="depts1" name="depts" type="checkbox" value="1" checked="checked" />
    <label for="depts1">开发部</label>
</span>