五. 复选框
复选框与单选框的用法,几乎是一样的。 这里也简单讲解一下。
五.一 单个复选框 form:checkbox
属性:
1 . 存放的是单值, 如 是否同意协议 这样的单个复选框。 为boolean 类型的值。
@RequestMapping(value="toLogin") public String toLogin(Model model){ User user=new User(); user.setName("老蝴蝶"); //设置性别为 男 user.setAgree(true); model.addAttribute("user",user); return "user/login"; }
前端页面展示:
<form:label path="agree"> 是否同意协议:</form:label> <!-- 注意,path用的是agree,而不是isAgree. 这就是boolean 属性值的区别 --> <form:checkbox path="agree"/>
前端展示:
源代码处理为:
<label for="agree"> 是否同意协议:</label> <input id="agree1" name="agree" type="checkbox" value="true" checked="checked"/><input type="hidden" name="_agree" value="on"/>
多添加了一个隐藏域 为_agree的值。
2 . 绑定多个单值, 与radiobutton 是一致的。
后端:
@RequestMapping(value="toLogin") public String toLogin(Model model){ User user=new User(); user.setName("老蝴蝶"); //设置爱好集合。 List<String> hobby=new ArrayList<String> (); hobby.add("打游戏"); hobby.add("编程"); user.setHobby(hobby); model.addAttribute("user",user); return "user/login"; }
前端展示:
<form:label path="hobby"> 爱好:</form:label> <!--用label来代替显示值 --> <form:checkbox path="hobby" value="读书" label="读书"/> <form:checkbox path="hobby" value="编程" label="编程"/> <form:checkbox path="hobby" value="打游戏" label="打游戏"/> <form:checkbox path="hobby" value="写作" label="写作"/>
前端回显展示:
绑定 int值,与上面的是一样的。 不详细介绍了。
可以将前台的爱好集合,也从后端读取。 这样,需要用复选框的集合形式。
五.二 单个复选框 form:checkboxes
属性有:
1 . 存储集合的形式, 单值的样式。
@RequestMapping(value="toLogin") public String toLogin(Model model){ User user=new User(); user.setName("老蝴蝶"); //设置爱好集合。 List<String> hobby=new ArrayList<String> (); hobby.add("打游戏"); hobby.add("编程"); user.setHobby(hobby); model.addAttribute("user",user); //后端返回 爱好的集合。 应该从数据库中查询。 List<String> hobbyList=new ArrayList<String>(); hobbyList.add("读书"); hobbyList.add("打游戏"); hobbyList.add("编程"); hobbyList.add("唱歌"); hobbyList.add("看小说"); model.addAttribute("hobbyList",hobbyList); return "user/login"; }
前端展示为:
<form:label path="hobby"> 爱好:</form:label> <form:checkboxes items="${hobbyList}" path="hobby"/>
页面显示
如果值相同,那么就进行勾选。
可以用delimiter 属性来进行分隔, 如 , 的形式。
<form:checkboxes items="${hobbyList}" path="hobby" delimiter=","/>
2 . 存储 Map 的形式, 也是单值。
@RequestMapping(value="toLogin") public String toLogin(Model model){ User user=new User(); user.setName("精灵妹"); //设置爱好集合。 List<String> hobby=new ArrayList<String> (); hobby.add("1"); hobby.add("4"); hobby.add("5"); user.setHobby(hobby); model.addAttribute("user",user); //后端返回 爱好的集合。 应该从数据库中查询。 Map<String,String> hobbyMap=new HashMap<String,String>(); hobbyMap.put("1","读书"); hobbyMap.put("2","打游戏"); hobbyMap.put("3","编程"); hobbyMap.put("4","唱歌"); hobbyMap.put("5","看小说"); model.addAttribute("hobbyMap",hobbyMap); return "user/login"; }
前端代码:
<form:label path="hobby"> 爱好:</form:label> <!--用label来代替显示值 --> <form:checkboxes items="${hobbyMap}" path="hobby"/>
前台展示:
3 .存储为集合的形式, 是javaBean的样式。
添加一个角色的类,Role . 为员工配置多个角色的形式。 这里,直接将Radio 单选框的SystemConn 进行扩展后进行测试。
后端:
//转到登录的页面 @RequestMapping(value="toLogin") public String toLogin(Model model){ User user=new User(); user.setName("精灵妹"); //设置该员工角色的集合。 List<Role> roles=new ArrayList<Role>(); Role urole1=new Role(); urole1.setId(1); urole1.setName("超级管理员"); Role urole2=new Role(); urole2.setId(4); urole2.setName("一般用户"); roles.add(urole1); roles.add(urole2); user.setRoles(roles); model.addAttribute("user",user); //后端返回 角色的集合。 应该从数据库中查询。 List<Role> roleList=new ArrayList<Role>(); Role role1=new Role(); role1.setId(1); role1.setName("超级管理员"); Role role2=new Role(); role2.setId(2); role2.setName("机构管理员"); Role role3=new Role(); role3.setId(3); role3.setName("系统管理员"); Role role4=new Role(); role4.setId(4); role4.setName("一般用户"); roleList.add(role1); roleList.add(role2); roleList.add(role3); roleList.add(role4); model.addAttribute("roleList",roleList); return "user/login"; }
前端展示:
<form:form modelAttribute="user" action="login.action" method="delete"> <form:label path="name">姓名:</form:label> <form:input path="name" cssClass="red"/> <br/> <form:label path="roles"> 角色:</form:label> <!--用label来代替显示值 --> <form:checkboxes items="${roleList}" path="roles" itemLabel="name" itemValue="id"/> </form:form>
运行服务器,前端显示:
发现,可以显示角色的集合,但是不能回显。
原因是对象不一致导致的。 role 的id 和name 虽然一一致,但是并不能说明两个对象是一致的。
可以简单做个测试。
roleList 集合中添加 urole1 对象。
roleList.add(urole1);
这时,前端展示为:
发现, urole1, 也就是最后面的 超级管理员被选中了。 可以进行回显。
最好的做法,是重写 Role 中的hashcode() 和equals() 方法,来表明当 id一致时, 这个角色就相同。
Role.java
package com.yjl.pojo; public class Role { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = 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; } }
后端处理代码:
//转到登录的页面 @RequestMapping(value="toLogin") public String toLogin(Model model){ User user=new User(); user.setName("精灵妹"); //设置该员工角色的集合。 List<Role> roles=new ArrayList<Role>(); Role urole1=new Role(); urole1.setId(1); Role urole2=new Role(); urole2.setId(4); roles.add(urole1); roles.add(urole2); user.setRoles(roles); model.addAttribute("user",user); //后端返回 角色的集合。 应该从数据库中查询。 List<Role> roleList=new ArrayList<Role>(); Role role1=new Role(); role1.setId(1); role1.setName("超级管理员"); Role role2=new Role(); role2.setId(2); role2.setName("机构管理员"); Role role3=new Role(); role3.setId(3); role3.setName("系统管理员"); Role role4=new Role(); role4.setId(4); role4.setName("一般用户"); roleList.add(role1); roleList.add(role2); roleList.add(role3); roleList.add(role4); model.addAttribute("roleList",roleList); return "user/login"; }
前端的代码,是一致的。不需要改变。
<form:label path="roles"> 角色:</form:label> <!--用label来代替显示值 --> <form:checkboxes items="${roleList}" path="roles" itemLabel="name" itemValue="id"/>
测试页面展示:
查看源代码为:
<label for="roles"> 角色:</label> <!--用label来代替显示值 --> <span><input id="roles1" name="roles" type="checkbox" value="1" checked="checked"/><label for="roles1">超级管理员</label></span><span><input id="roles2" name="roles" type="checkbox" value="2"/><label for="roles2">机构管理员</label></span><span><input id="roles3" name="roles" type="checkbox" value="3"/><label for="roles3">系统管理员</label></span><span><input id="roles4" name="roles" type="checkbox" value="4" checked="checked"/><label for="roles4">一般用户</label></span><input type="hidden" name="_roles" value="on"/>
这就是 checkboxes 的基本的用法。
六. Select 选择框
input type=“select”, 关于select 框的表现,有三种标签。 一个是 form:select, 一个是 form:option, 还有一个是form:options
这些用法,与 复选框和单选框的用法是一致的。 可以类比化使用。 这里,只简单介绍一下。
form:select 的属性展示:
六.一 form:select 的Map 形式。 单选。
后端代码:
//转到登录的页面 @RequestMapping(value="toLogin") public String toLogin(Model model){ User user=new User(); user.setName("两个蝴蝶飞"); //设置该员工角色的集合。 user.setAddr("2"); Map<String,String> addrMap=new HashMap<String,String> (); addrMap.put("1","浦东新区"); addrMap.put("2","松江"); addrMap.put("3","徐汇"); addrMap.put("4","杨浦"); model.addAttribute("user",user); model.addAttribute("addrMap",addrMap); return "user/login"; }
前端展示:
<form:label path="roles">城市:</form:label> <!--用label来代替显示值 --> <form:select items="${addrMap}" path="addr"/>
页面展示
select 框,可以单选,也可以进行多选。
六.二 form:select 的Map 形式, 多选。
后端:
@RequestMapping(value="toLogin") public String toLogin(Model model){ User user=new User(); user.setName("两个蝴蝶飞"); //设置该员工角色的集合。 List<String> jobList=new ArrayList<String>(); jobList.add("1"); jobList.add("2"); user.setJob(jobList); Map<String,String> jobMap=new HashMap<String,String> (); jobMap.put("1","Java"); jobMap.put("2","数据库"); jobMap.put("3","Python"); jobMap.put("4","大数据"); model.addAttribute("user",user); model.addAttribute("jobMap",jobMap); return "user/login"; }
前端展示:
<form:label path="job">职业:</form:label> <!--不需要设置 multiple="multiple" --> <form:select items="${jobMap}" path="job"/>
展示:
查看源代码:
<label for="job">职业:</label> <!--用label来代替显示值 --> <select id="job" name="job" multiple="multiple"><option value="1" selected="selected">Java</option><option value="2" selected="selected">数据库</option><option value="3">Python</option><option value="4">大数据</option></select><input type="hidden" name="_job" value="1"/>
六.三 form:option 单值选项
属性有:
form:select 会直接将所有的选项都展示出来, 直接全部填充 option 中的值。 有的时候,不太友好 。 如 option 的开头常常有 ‘请选择’ 之类的提示语。
以单个选项值为例, 即与 addr 为例子看一下。
后端:
@RequestMapping(value="toLogin") public String toLogin(Model model){ User user=new User(); user.setName("两个蝴蝶飞"); //设置该员工角色的集合。 user.setAddr("2"); Map<String,String> addrMap=new HashMap<String,String> (); addrMap.put("1","浦东新区"); addrMap.put("2","松江"); addrMap.put("3","徐汇"); addrMap.put("4","杨浦"); model.addAttribute("user",user); model.addAttribute("addrMap",addrMap); return "user/login"; }
前台展示: option 是一个个手写的。
<form:label path="addr">城市:</form:label> <!--用label来代替显示值 --> <form:select path="addr"> <!-- 单值的时候,option 与form:option 是一致的,没有差别。 --> <option value="">请选择</option> <option value="1">浦东新区</option> <form:option value="2">松江</form:option> <form:option value="3">徐汇</form:option> <form:option value="4">杨浦</form:option> </form:select>
前台样式:
六.四 form:select 与 form:option 同时出现,显示哪一个。
后端的代码保持不变。
前端代码:
<form:label path="addr">城市:</form:label> <!--用label来代替显示值 --> <form:select items="${addrMap}" path="addr"> <!-- 单值的时候,option 与form:option 是一致的,没有差别。 --> <option value="">请选择1</option> <option value="5">浦东新区1</option> <form:option value="6">松江1</form:option> <form:option value="7">徐汇1</form:option> <form:option value="8">杨浦1</form:option> </form:select>
样式展示:
发现, 是以 form:select 为主, form:option 中的值不显示。
六.五 form:options
属性有:
当选项过多的时候,又想要添加’请选择’ 选项的时候,即结合 form:select 与form:option 的优点,可以用 form:options
后端代码保持不变。
前端代码:
<form:label path="addr">城市:</form:label> <!--用label来代替显示值 --> <form:select path="addr"> <option value="">请选择城市</option> <form:options items="${addrMap}"/> </form:select>
前端展示:
可以将 form:option 与form:options 连用
<form:select path="addr"> <form:option value="">请选择城市</form:option> <form:options items="${addrMap}"/> </form:select>
相同的效果。
form:select, form:options 也可以用 itemLabel itemValue ,封闭 javaBean 的对象,如Role 对象。 与form:checkboxes 一致,不要忘记重写 Role 里面的equals() 和hashCode() 方法。 这里就不举例了。
七. form:errors 标签
属性有:
验证,会有一个专门的章节讲解。 老蝴蝶在这里简单的举个例子吧。
七.一 先写一个 User的验证器 UserValidator
package com.yjl.validator; import org.springframework.validation.Errors; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator; import com.yjl.pojo.User; public class UserValidator implements Validator{ @Override public boolean supports(Class<?> arg0) { return User.class.equals(arg0); } @Override public void validate(Object arg0, Errors errors) { //后面是 提示的语句,在国际化时,需要进行提示语句的国际化 ValidationUtils.rejectIfEmpty(errors, "name",null,"name is null"); ValidationUtils.rejectIfEmpty(errors, "age",null,"age is null"); } }
七.二 后端数据处理,添加绑定验证器
//初始化绑定 @InitBinder public void initBinder(DataBinder binder) { binder.setValidator(new UserValidator()); } //转到登录的页面 @RequestMapping(value="toLogin") public String toLogin(Model model){ User user=new User(); user.setName("老蝴蝶"); model.addAttribute("user",user); return "user/login"; } //绑定到user对象。 @RequestMapping(value="login") public String login(@Validated User user, Errors errors){ if(errors.hasFieldErrors()){ //有错误字段 return "user/login"; } return "user/list"; }
七.三 前端显示
<h2>两个蝴蝶飞,form表单使用</h2> <form:form modelAttribute="user" action="login.action" method="post"> <form:label path="name">姓名:</form:label> <form:input path="name"/> <form:errors path="name"></form:errors> <br/> <form:label path="age">年龄:</form:label> <form:input path="age"/> <form:errors path="age"></form:errors> <br/> <form:button>提交</form:button> </form:form> </body>
当输入时, 不输入年龄,进行提交时,age提示错误。
当年龄和名称都不输入时,提示两个都是空。
七.四 form:errors 中path的写法
有三种写法。
1 .* , 即path=x (x实际 为 8键盘上的星星,打不出来。 下面的也是一样。) 时,是所有的。 所有的没有通过验证的字段,都放置在这里面。
<form:label path="age">年龄:</form:label> <form:input path="age"/> <form:errors path="*"></form:errors> <br/>
年龄,名称都不输入时:
2 . 前缀*, 即path= 前缀x, 是所有以这个为开头的 。
<form:label path="age">年龄:</form:label> <form:input path="age"/> <form:errors path="ag*"></form:errors> <br/>
年龄不输入时,
3 . 准确定位, 用path= 名称。 只接收该名称的错误。
<form:label path="age">年龄:</form:label> <form:input path="age"/> <form:errors path="age"></form:errors> <br/>
年龄不输入时, 显示错误。 年龄输入,而姓名不输入时,不接收错误。
这就是form表单标签的使用。 老蝴蝶先歇会。
谢谢!!!