SSM-CRUD入门项目——新增与校验
新增
分析:
在Index.jsp页面点击新增,弹出对话框(模态框)
数据库查询部门列表显示在模态框中
用户输入数据完成操作
我们先把模态框构建出来,并对新增按钮添加事件,点击按钮弹出模态框:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!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>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <!-- 员工新增模态框 --> <div class="modal fade" id="addEmpModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="myModalLabel">添加员工</h4> </div> <div class="modal-body"> <form class="form-horizontal"> <!-- 输入员工姓名 --> <div class="form-group"> <label for="input_empName" class="col-sm-2 control-label">empName</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="input_empName" placeholder="empName"> </div> </div> <!-- 输入员工邮箱 --> <div class="form-group"> <label for="input_email" class="col-sm-2 control-label">email</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="input_email" placeholder="email"> </div> </div> <!-- 选择员工性别 --> <div class="form-group"> <label class="col-sm-2 control-label">gender</label> <div class="col-sm-2"> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="M" checked> 男 </label> </div> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="F"> 女 </label> </div> </div> </div> <!-- 部门名称 --> <div class="form-group"> <label class="col-sm-2 control-label">deptName</label> <div class="col-sm-2"> <!-- 部门名称是变动的,这里保存员工是只保存ID的形式 --> <select class="form-control" name="dId"> </select> </div> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary">保存</button> </div> </div> </div> </div> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary" id="addBtn_modal">新增</button> <button type="button" class="btn btn-danger ">删除</button> </div> </div> <!-- 表格 --> <div class="row"> <div class="col-md-12"> <table class="table table-hover" id="emps_table"> <thead> <tr> <th>#</th> <th>empName</th> <th>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //清空表格数据 $("#emps_table tbody").empty(); //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(deptNameTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //清空分页数据 $("#page_info").empty(); //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //清空分页导航信息 $("#page_nav").empty(); //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); }else{ //添加首页和前一页翻页的单机事件 firstPageLi.click(function(){ toPage(1); }); prePageLi.click(function(){ toPage(result.map.pageInfo.pageNum-1); }); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); }else{ //添加末页和后一页翻页的单机事件 lastPageLi.click(function(){ toPage(result.map.pageInfo.pages); }); nextPageLi.click(function(){ toPage(result.map.pageInfo.pageNum+1); }); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); //li加入ul,ul加入nav navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } //增加员工的事件 $("#addBtn_modal").click(function(){ $('#addEmpModal').modal({ backdrop:false }); }); </script> </body> </html>
由于部门信息是变动的,在弹出模态框之前我们添加发送ajax请求查询部门信息进行显示,核心添加代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//增加员工的事件 $("#addBtn_modal").click(function(){ //发送ajax请求查询部门信息 getDepts(); //弹出模态框 $('#addEmpModal').modal({ backdrop:false }); }); //得到部门信息的函数 function getDepts(){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/depts", //请求要带的数据,这里无需带数据 //请求成功的回调函数 success : function(result) { $.each(result.map.deptList,function(){ //这里换用不传参的方式,采用this引用正在遍历的对象 var optionEle = $("<option></option>").append(this.deptName).attr("value",this.deptId); optionEle.appendTo("#addEmpModal select"); }); } }); }
由于发送了相关的请求,我们完善的对应的controller如下:DeptController.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package cn.crud.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import cn.crud.bean.Department; import cn.crud.bean.Msg; import cn.crud.service.DeptService; /** * 处理和部门有关的请求的controller * @author Administrator * */ @Controller public class DeptController { //controller中注入service @Autowired private DeptService deptService; /** * 返回部门信息的controller方法 * @return */ @RequestMapping("/depts") @ResponseBody public Msg getDepts(){ //查出所有部门信息 List<Department> deptList = deptService.getDepts(); //调用Msg的静态方法,返回我们自定义的数据 return Msg.success().add("deptList", deptList); } }
相应的service:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package cn.crud.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import cn.crud.bean.Department; import cn.crud.dao.DepartmentMapper; /** * 处理部门的service * @author Administrator * */ @Service public class DeptService { //注入mapper @Autowired private DepartmentMapper departmentMapper; /** * 返回所有部门信息的方法 * @return */ public List<Department> getDepts() { List<Department> deptList = departmentMapper.selectByExample(null); return deptList; } }
其他的ajax请求也是这么个流程,接下来把添加员工的ajax请求完成一下:
这里引入REST的风格的URI
/emp/{id} GET请求 查询员工
/emp POST请求 保存员工
/emp/{id} DELETE请求 删除员工
/emp/{id} PUT请求 修改员工
//序列化表单数据的jQuery方法:
serialize()——详细介绍请参见API
这样,我们的添加的逻辑的页面如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!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>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <!-- 员工新增模态框 --> <div class="modal fade" id="addEmpModal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span>×</span></button> <h4 class="modal-title" id="myModalLabel">添加员工</h4> </div> <div class="modal-body"> <form class="form-horizontal"> <!-- 输入员工姓名 --> <div class="form-group"> <label for="input_empName" class="col-sm-2 control-label">empName</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="input_empName" placeholder="empName"> </div> </div> <!-- 输入员工邮箱 --> <div class="form-group"> <label for="input_email" class="col-sm-2 control-label">email</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="input_email" placeholder="email"> </div> </div> <!-- 选择员工性别 --> <div class="form-group"> <label class="col-sm-2 control-label">gender</label> <div class="col-sm-2"> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="M" checked> 男 </label> </div> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="F"> 女 </label> </div> </div> </div> <!-- 部门名称 --> <div class="form-group"> <label class="col-sm-2 control-label">deptName</label> <div class="col-sm-4" style="width:120px"> <!-- 部门名称是变动的,这里保存员工是只保存ID的形式 --> <select class="form-control" name="dId"> </select> </div> </div> </form> </div> <!-- 页脚按钮操作 --> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="emp_saveBtn">保存</button> </div> </div> </div> </div> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary" id="addBtn_modal">新增</button> <button type="button" class="btn btn-danger ">删除</button> </div> </div> <!-- 表格 --> <div class="row"> <div class="col-md-12"> <table class="table table-hover" id="emps_table"> <thead> <tr> <th>#</th> <th>empName</th> <th>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //清空表格数据 $("#emps_table tbody").empty(); //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(deptNameTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //清空分页数据 $("#page_info").empty(); //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //清空分页导航信息 $("#page_nav").empty(); //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); }else{ //添加首页和前一页翻页的单机事件 firstPageLi.click(function(){ toPage(1); }); prePageLi.click(function(){ toPage(result.map.pageInfo.pageNum-1); }); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); }else{ //添加末页和后一页翻页的单机事件 lastPageLi.click(function(){ toPage(result.map.pageInfo.pages); }); nextPageLi.click(function(){ toPage(result.map.pageInfo.pageNum+1); }); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); //li加入ul,ul加入nav navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } //增加员工的事件 $("#addBtn_modal").click(function(){ //发送ajax请求查询部门信息 getDepts(); //弹出模态框 $('#addEmpModal').modal({ backdrop:false }); }); //得到部门信息的函数 function getDepts(){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/depts", //请求要带的数据,这里无需带数据 //请求成功的回调函数 success : function(result) { $.each(result.map.deptList,function(){ //这里换用不传参的方式,采用this引用正在遍历的对象 var optionEle = $("<option></option>").append(this.deptName).attr("value",this.deptId); optionEle.appendTo("#addEmpModal select"); }); } }); } //为添加员工的保存按钮绑定单击事件 $("#emp_saveBtn").click(function(){ //模态框中保存按钮发送ajax请求 $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/emp", //请求要带的数据,这里是模态框中的值, //这里应该采用的是jQuery的序列化表单的方法进行提取表单数据,serialize(); //表单序列化的数据:$("#addEmpModal form").serialize(); data:$("#addEmpModal form").serialize(), //请求成功的回调函数 success : function(result) { alert("保存成功!"); } }); }); </script> </body> </html>
【更新】:jQuery表单的序列化
1..serialize()——序列化为:a=1&b=2&c=3&d=4&e=5 格式的字符串(springMVC中可直接通过POJO形参接收)
2.serializeArray()——序列化为:
[
{name: 'firstname', value: 'Hello'},
{name: 'lastname', value: 'World'},
{name: 'alias'}, // 值为空
]
详细请参见:http://www.w3school.com.cn/jquery/jquery_ref_ajax.asp
相应的controller:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package cn.crud.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import cn.crud.bean.Employee; import cn.crud.bean.Msg; import cn.crud.service.EmpService; /** * 处理员工的CRUD请求 * @author Administrator * */ @Controller public class EmpController { @Autowired private EmpService empService; /** * 处理添加员工的ajax请求的方法 * @return */ @RequestMapping(value="/emp",method=RequestMethod.POST) @ResponseBody public Msg saveEmp(Employee employee){ empService.saveEmp(employee); return Msg.success(); } /** * 分页信息的AJAX请求 * @ResponseBody可以将返回的对象转为JSON字符串 * 此注解需要引入jackson的包(以及注解驱动的配置等,这里已经进行配置) * 将返回信息包装在msg里 */ @RequestMapping("/emps") @ResponseBody public Msg getEmpsWithJson(@RequestParam(value="pn",defaultValue="1") Integer pn, Model model){ //改造为一个分页查询 //在查询之前传入分页参数:起始页和每页记录数 PageHelper.startPage(pn, 5); //后面紧跟的查询就是分页查询 List<Employee> empList = empService.getAll(); //用PageInfo对结果进行包装,只需要将PageInfo交给页面即可,这里面封装了详细的信息,第二个参数为需要连续显示的记录数 PageInfo page = new PageInfo(empList,5); //直接将pageInfo对象进行返回 //将pageInfo放在msg里进行返回,链式操作返回对象本身 return Msg.success().add("pageInfo", page); } /** * 分页查询员工数据 */ //@RequestMapping("/emps") public String getEmps(@RequestParam(value="pn",defaultValue="1") Integer pn, Model model){ //改造为一个分页查询 //在查询之前传入分页参数:起始页和每页记录数 PageHelper.startPage(pn, 5); //后面紧跟的查询就是分页查询 List<Employee> empList = empService.getAll(); //用PageInfo对结果进行包装,只需要将PageInfo交给页面即可,这里面封装了详细的信息,第二个参数为需要连续显示的记录数 PageInfo page = new PageInfo(empList,5); model.addAttribute("pageInfo", page); return "list"; } }
service:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package cn.crud.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import cn.crud.bean.Employee; import cn.crud.dao.EmployeeMapper; /** * 处理员工的service * @author Administrator * */ @Service public class EmpService { @Autowired private EmployeeMapper employeeMapper; /** * 查询所有员工 * @return */ public List<Employee> getAll() { /** * 没有查询条件的查询所有,带部门信息 */ return employeeMapper.selectByExampleWithDept(null); } /** * 增加员工 * @param employee */ public void saveEmp(Employee employee) { //我们选择有选择的保存,因为ID是自增的 employeeMapper.insertSelective(employee); } }
我们进行简单的测试:
//我们容易发现一点小问题:
1.保存成功后模态框应该关闭
2.列表应该来到最后一页
我们来进行完善:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!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>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <!-- 员工新增模态框 --> <div class="modal fade" id="addEmpModal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span>×</span></button> <h4 class="modal-title" id="myModalLabel">添加员工</h4> </div> <div class="modal-body"> <form class="form-horizontal"> <!-- 输入员工姓名 --> <div class="form-group"> <label for="input_empName" class="col-sm-2 control-label">empName</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="input_empName" placeholder="empName"> </div> </div> <!-- 输入员工邮箱 --> <div class="form-group"> <label for="input_email" class="col-sm-2 control-label">email</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="input_email" placeholder="email"> </div> </div> <!-- 选择员工性别 --> <div class="form-group"> <label class="col-sm-2 control-label">gender</label> <div class="col-sm-2"> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="M" checked> 男 </label> </div> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="F"> 女 </label> </div> </div> </div> <!-- 部门名称 --> <div class="form-group"> <label class="col-sm-2 control-label">deptName</label> <div class="col-sm-4" style="width:120px"> <!-- 部门名称是变动的,这里保存员工是只保存ID的形式 --> <select class="form-control" name="dId"> </select> </div> </div> </form> </div> <!-- 页脚按钮操作 --> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="emp_saveBtn">保存</button> </div> </div> </div> </div> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary" id="addBtn_modal">新增</button> <button type="button" class="btn btn-danger ">删除</button> </div> </div> <!-- 表格 --> <div class="row"> <div class="col-md-12"> <table class="table table-hover" id="emps_table"> <thead> <tr> <th>#</th> <th>empName</th> <th>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //全局总记录数,用于查最后一页 var golbalTotalCount; //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //清空表格数据 $("#emps_table tbody").empty(); //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(deptNameTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //清空分页数据 $("#page_info").empty(); //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; //给全局记录数赋值 golbalTotalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //清空分页导航信息 $("#page_nav").empty(); //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); }else{ //添加首页和前一页翻页的单机事件 firstPageLi.click(function(){ toPage(1); }); prePageLi.click(function(){ toPage(result.map.pageInfo.pageNum-1); }); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); }else{ //添加末页和后一页翻页的单机事件 lastPageLi.click(function(){ toPage(result.map.pageInfo.pages); }); nextPageLi.click(function(){ toPage(result.map.pageInfo.pageNum+1); }); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); //li加入ul,ul加入nav navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } //增加员工的事件 $("#addBtn_modal").click(function(){ //发送ajax请求查询部门信息 getDepts(); //弹出模态框 $('#addEmpModal').modal({ backdrop:false }); }); //得到部门信息的函数 function getDepts(){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/depts", //请求要带的数据,这里无需带数据 //请求成功的回调函数 success : function(result) { $.each(result.map.deptList,function(){ //这里换用不传参的方式,采用this引用正在遍历的对象 var optionEle = $("<option></option>").append(this.deptName).attr("value",this.deptId); optionEle.appendTo("#addEmpModal select"); }); } }); } //为添加员工的保存按钮绑定单击事件 $("#emp_saveBtn").click(function(){ //模态框中保存按钮发送ajax请求 $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/emp", //请求要带的数据,这里是模态框中的值, //这里应该采用的是jQuery的序列化表单的方法进行提取表单数据,serialize(); //表单序列化的数据:$("#addEmpModal form").serialize(); data:$("#addEmpModal form").serialize(), //请求成功的回调函数 success : function(result) { //alert(result.msg); //1.成功完成模态框 $("#addEmpModal").modal('hide') //2.来到列表最后一页 //发送ajax请求,显示最后一页,因为插件做了参数合理化配置,可以配置一个比较大的数字 //这样,查到的总是最后一页记录,我们使用全局的总记录数 toPage(golbalTotalCount); } }); }); </script> </body> </html>
//主要做的事情是两个函数的处理,这里利用分页插件的合理化参数进行简化操作
这样,我们基本添加功能就完成了!
接下来,我们进行添加功能的前端校验,在完成保存添加之前,进行表单数据校验:
//更新jQuery的获取表单数据的三个方法,详细请参见w3school API (复习jQuery)
- text() - 设置或返回所选元素的文本内容
- html() - 设置或返回所选元素的内容(包括 HTML 标记)
- val() - 设置或返回表单字段的值
我们对校验部分进行完成:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!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>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <!-- 员工新增模态框 --> <div class="modal fade" id="addEmpModal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span>×</span></button> <h4 class="modal-title" id="myModalLabel">添加员工</h4> </div> <div class="modal-body"> <form class="form-horizontal"> <!-- 输入员工姓名 --> <div class="form-group"> <label for="input_empName" class="col-sm-2 control-label">empName</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="input_empName" placeholder="empName"> </div> </div> <!-- 输入员工邮箱 --> <div class="form-group"> <label for="input_email" class="col-sm-2 control-label">email</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="input_email" placeholder="email"> </div> </div> <!-- 选择员工性别 --> <div class="form-group"> <label class="col-sm-2 control-label">gender</label> <div class="col-sm-2"> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="M" checked> 男 </label> </div> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="F"> 女 </label> </div> </div> </div> <!-- 部门名称 --> <div class="form-group"> <label class="col-sm-2 control-label">deptName</label> <div class="col-sm-4" style="width:120px"> <!-- 部门名称是变动的,这里保存员工是只保存ID的形式 --> <select class="form-control" name="dId"> </select> </div> </div> </form> </div> <!-- 页脚按钮操作 --> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="emp_saveBtn">保存</button> </div> </div> </div> </div> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary" id="addBtn_modal">新增</button> <button type="button" class="btn btn-danger ">删除</button> </div> </div> <!-- 表格 --> <div class="row"> <div class="col-md-12"> <table class="table table-hover" id="emps_table"> <thead> <tr> <th>#</th> <th>empName</th> <th>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //全局总记录数,用于查最后一页 var golbalTotalCount; //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //清空表格数据 $("#emps_table tbody").empty(); //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(emailTd) .append(genderTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //清空分页数据 $("#page_info").empty(); //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; //给全局记录数赋值 golbalTotalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //清空分页导航信息 $("#page_nav").empty(); //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); }else{ //添加首页和前一页翻页的单机事件 firstPageLi.click(function(){ toPage(1); }); prePageLi.click(function(){ toPage(result.map.pageInfo.pageNum-1); }); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); }else{ //添加末页和后一页翻页的单机事件 lastPageLi.click(function(){ toPage(result.map.pageInfo.pages); }); nextPageLi.click(function(){ toPage(result.map.pageInfo.pageNum+1); }); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); //li加入ul,ul加入nav navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } //增加员工的事件 $("#addBtn_modal").click(function(){ //发送ajax请求查询部门信息 getDepts(); //弹出模态框 $('#addEmpModal').modal({ backdrop:false }); }); //得到部门信息的函数 function getDepts(){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/depts", //请求要带的数据,这里无需带数据 //请求成功的回调函数 success : function(result) { $.each(result.map.deptList,function(){ //这里换用不传参的方式,采用this引用正在遍历的对象 var optionEle = $("<option></option>").append(this.deptName).attr("value",this.deptId); optionEle.appendTo("#addEmpModal select"); }); } }); } //添加表单数据的校验 function validate_add_form(){ //1.获取需要校验的值 //2.使用jQuery正则(api中常用正则)进行校验(校验插件的使用待更新) var empNameVal = $("#input_empName").val(); //校验的正则表达式(可以搜索常用正则) var regName = /(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5}$)/; //开始校验用户名 if(!regName.test(empNameVal)){ alert("用户名只能是6-16位英文数字或2-5位汉字组合!"); return false; } //同理,校验邮箱 var empEmailVal = $("#input_email").val(); var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/; //开始校验邮箱 if(!regEmail.test(empEmailVal)){ alert("邮箱不合法!"); return false; } return true; } //为添加员工的保存按钮绑定单击事件 $("#emp_saveBtn").click(function(){ //1.进行表单数据的校验 if(!validate_add_form()){ return false; } //2.模态框中保存按钮发送ajax请求 $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/emp", //请求要带的数据,这里是模态框中的值, //这里应该采用的是jQuery的序列化表单的方法进行提取表单数据,serialize(); //表单序列化的数据:$("#addEmpModal form").serialize(); data:$("#addEmpModal form").serialize(), //请求成功的回调函数 success : function(result) { //alert(result.msg); //1.成功完成模态框 $("#addEmpModal").modal('hide') //2.来到列表最后一页 //发送ajax请求,显示最后一页,因为插件做了参数合理化配置,可以配置一个比较大的数字 //这样,查到的总是最后一页记录,我们使用全局的总记录数 toPage(golbalTotalCount); } }); }); </script> </body> </html>
简单测试:
当然,这种样式与体验是比较不好的,我们使用bootstrap的样式进行改善:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!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>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <!-- 员工新增模态框 --> <div class="modal fade" id="addEmpModal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span>×</span></button> <h4 class="modal-title" id="myModalLabel">添加员工</h4> </div> <div class="modal-body"> <form class="form-horizontal"> <!-- 输入员工姓名 --> <div class="form-group"> <label for="input_empName" class="col-sm-2 control-label">empName</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="input_empName" placeholder="empName"> <span class="help-block"></span> </div> </div> <!-- 输入员工邮箱 --> <div class="form-group"> <label for="input_email" class="col-sm-2 control-label">email</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="input_email" placeholder="email"> <span class="help-block"></span> </div> </div> <!-- 选择员工性别 --> <div class="form-group"> <label class="col-sm-2 control-label">gender</label> <div class="col-sm-2"> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="M" checked> 男 </label> </div> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="F"> 女 </label> </div> </div> </div> <!-- 部门名称 --> <div class="form-group"> <label class="col-sm-2 control-label">deptName</label> <div class="col-sm-4" style="width:120px"> <!-- 部门名称是变动的,这里保存员工是只保存ID的形式 --> <select class="form-control" name="dId"> </select> </div> </div> </form> </div> <!-- 页脚按钮操作 --> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="emp_saveBtn">保存</button> </div> </div> </div> </div> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary" id="addBtn_modal">新增</button> <button type="button" class="btn btn-danger ">删除</button> </div> </div> <!-- 表格 --> <div class="row"> <div class="col-md-12"> <table class="table table-hover" id="emps_table"> <thead> <tr> <th>#</th> <th>empName</th> <th>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //全局总记录数,用于查最后一页 var golbalTotalCount; //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //清空表格数据 $("#emps_table tbody").empty(); //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(emailTd) .append(genderTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //清空分页数据 $("#page_info").empty(); //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; //给全局记录数赋值 golbalTotalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //清空分页导航信息 $("#page_nav").empty(); //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); }else{ //添加首页和前一页翻页的单机事件 firstPageLi.click(function(){ toPage(1); }); prePageLi.click(function(){ toPage(result.map.pageInfo.pageNum-1); }); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); }else{ //添加末页和后一页翻页的单机事件 lastPageLi.click(function(){ toPage(result.map.pageInfo.pages); }); nextPageLi.click(function(){ toPage(result.map.pageInfo.pageNum+1); }); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); //li加入ul,ul加入nav navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } //增加员工的事件 $("#addBtn_modal").click(function(){ //发送ajax请求查询部门信息 getDepts(); //弹出模态框 $('#addEmpModal').modal({ backdrop:false }); }); //得到部门信息的函数 function getDepts(){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/depts", //请求要带的数据,这里无需带数据 //请求成功的回调函数 success : function(result) { $.each(result.map.deptList,function(){ //这里换用不传参的方式,采用this引用正在遍历的对象 var optionEle = $("<option></option>").append(this.deptName).attr("value",this.deptId); optionEle.appendTo("#addEmpModal select"); }); } }); } //添加表单数据的校验 function validate_add_form(){ //1.获取需要校验的值 //2.使用jQuery正则(api中常用正则)进行校验(校验插件的使用待更新) var empNameVal = $("#input_empName").val(); //校验的正则表达式(可以搜索常用正则) var regName = /(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5}$)/; //开始校验用户名 if(!regName.test(empNameVal)){ //alert("用户名只能是6-16位英文数字或2-5位汉字组合!"); //将提示信息优化,使用bootstrap的样式,给父元素添加相应的类即可 $("#input_empName").parent().addClass("has-error"); $("#input_empName").next(".help-block").text("用户名只能是6-16位英文数字或2-5位汉字组合!"); return false; }else{ $("#input_empName").parent().addClass("has-success"); $("#input_empName").next(".help-block").text("用户名正确!"); } //同理,校验邮箱 var empEmailVal = $("#input_email").val(); var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/; //开始校验邮箱 if(!regEmail.test(empEmailVal)){ //alert("邮箱不合法!"); $("#input_email").parent().addClass("has-error"); $("#input_email").next(".help-block").text("邮箱不合法!"); return false; }else{ $("#input_email").parent().addClass("has-success"); $("#input_email").next(".help-block").text("邮箱格式正确!"); } return true; } //为添加员工的保存按钮绑定单击事件 $("#emp_saveBtn").click(function(){ //1.进行表单数据的校验 if(!validate_add_form()){ return false; } //2.模态框中保存按钮发送ajax请求 $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/emp", //请求要带的数据,这里是模态框中的值, //这里应该采用的是jQuery的序列化表单的方法进行提取表单数据,serialize(); //表单序列化的数据:$("#addEmpModal form").serialize(); data:$("#addEmpModal form").serialize(), //请求成功的回调函数 success : function(result) { //alert(result.msg); //1.成功完成模态框 $("#addEmpModal").modal('hide') //2.来到列表最后一页 //发送ajax请求,显示最后一页,因为插件做了参数合理化配置,可以配置一个比较大的数字 //这样,查到的总是最后一页记录,我们使用全局的总记录数 toPage(golbalTotalCount); } }); }); </script> </body> </html>
这样,我们得到校验的结果:
很明显,这个校验存在问题,
我们右键,检查,查看原因:
//我们可以发现,这里是进行了追加,而不是替换,我们需要进行改善:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!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>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <!-- 员工新增模态框 --> <div class="modal fade" id="addEmpModal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span>×</span></button> <h4 class="modal-title" id="myModalLabel">添加员工</h4> </div> <div class="modal-body"> <form class="form-horizontal"> <!-- 输入员工姓名 --> <div class="form-group"> <label for="input_empName" class="col-sm-2 control-label">empName</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="input_empName" placeholder="empName"> <span class="help-block"></span> </div> </div> <!-- 输入员工邮箱 --> <div class="form-group"> <label for="input_email" class="col-sm-2 control-label">email</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="input_email" placeholder="email"> <span class="help-block"></span> </div> </div> <!-- 选择员工性别 --> <div class="form-group"> <label class="col-sm-2 control-label">gender</label> <div class="col-sm-2"> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="M" checked> 男 </label> </div> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="F"> 女 </label> </div> </div> </div> <!-- 部门名称 --> <div class="form-group"> <label class="col-sm-2 control-label">deptName</label> <div class="col-sm-4" style="width:120px"> <!-- 部门名称是变动的,这里保存员工是只保存ID的形式 --> <select class="form-control" name="dId"> </select> </div> </div> </form> </div> <!-- 页脚按钮操作 --> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="emp_saveBtn">保存</button> </div> </div> </div> </div> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary" id="addBtn_modal">新增</button> <button type="button" class="btn btn-danger ">删除</button> </div> </div> <!-- 表格 --> <div class="row"> <div class="col-md-12"> <table class="table table-hover" id="emps_table"> <thead> <tr> <th>#</th> <th>empName</th> <th>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //全局总记录数,用于查最后一页 var golbalTotalCount; //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //清空表格数据 $("#emps_table tbody").empty(); //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(emailTd) .append(genderTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //清空分页数据 $("#page_info").empty(); //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; //给全局记录数赋值 golbalTotalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //清空分页导航信息 $("#page_nav").empty(); //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); }else{ //添加首页和前一页翻页的单机事件 firstPageLi.click(function(){ toPage(1); }); prePageLi.click(function(){ toPage(result.map.pageInfo.pageNum-1); }); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); }else{ //添加末页和后一页翻页的单机事件 lastPageLi.click(function(){ toPage(result.map.pageInfo.pages); }); nextPageLi.click(function(){ toPage(result.map.pageInfo.pageNum+1); }); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); //li加入ul,ul加入nav navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } //增加员工的事件 $("#addBtn_modal").click(function(){ //发送ajax请求查询部门信息 getDepts(); //弹出模态框 $('#addEmpModal').modal({ backdrop:false }); }); //得到部门信息的函数 function getDepts(){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/depts", //请求要带的数据,这里无需带数据 //请求成功的回调函数 success : function(result) { $.each(result.map.deptList,function(){ //这里换用不传参的方式,采用this引用正在遍历的对象 var optionEle = $("<option></option>").append(this.deptName).attr("value",this.deptId); optionEle.appendTo("#addEmpModal select"); }); } }); } //添加表单数据的校验 function validate_add_form(){ //1.获取需要校验的值 //2.使用jQuery正则(api中常用正则)进行校验(校验插件的使用待更新) var empNameVal = $("#input_empName").val(); //校验的正则表达式(可以搜索常用正则) var regName = /(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5}$)/; //开始校验用户名 if(!regName.test(empNameVal)){ //alert("用户名只能是6-16位英文数字或2-5位汉字组合!"); //将提示信息优化,使用bootstrap的样式,给父元素添加相应的类即可 vilidate_form("#input_empName","error","用户名只能是6-16位英文数字或2-5位汉字组合!"); //$("#input_empName").parent().addClass("has-error"); //$("#input_empName").next(".help-block").text("用户名只能是6-16位英文数字或2-5位汉字组合!"); return false; }else{ vilidate_form("#input_empName","success","用户名正确!"); //$("#input_empName").parent().addClass("has-success"); //$("#input_empName").next(".help-block").text("用户名正确!"); } //同理,校验邮箱 var empEmailVal = $("#input_email").val(); var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/; //开始校验邮箱 if(!regEmail.test(empEmailVal)){ //alert("邮箱不合法!"); vilidate_form("#input_email","error","邮箱不合法!"); //$("#input_email").parent().addClass("has-error"); //$("#input_email").next(".help-block").text("邮箱不合法!"); return false; }else{ vilidate_form("#input_email","success","邮箱格式正确!"); //$("#input_email").parent().addClass("has-success"); //$("#input_email").next(".help-block").text("邮箱格式正确!"); } return true; } //重新抽取校验函数完成之前重复样式的清除工作 function vilidate_form(ele,status,msg){ //清除当前校验状态 $(ele).parent().removeClass("has-success has-error"); $(ele).next(".help-block").text(""); if("success" == status){ $(ele).parent().addClass("has-success"); $(ele).next(".help-block").text(msg); }else if("error" == status){ $(ele).parent().addClass("has-error"); $(ele).next(".help-block").text(msg); } } //为添加员工的保存按钮绑定单击事件 $("#emp_saveBtn").click(function(){ //1.进行表单数据的校验 if(!validate_add_form()){ return false; } //2.模态框中保存按钮发送ajax请求 $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/emp", //请求要带的数据,这里是模态框中的值, //这里应该采用的是jQuery的序列化表单的方法进行提取表单数据,serialize(); //表单序列化的数据:$("#addEmpModal form").serialize(); data:$("#addEmpModal form").serialize(), //请求成功的回调函数 success : function(result) { //alert(result.msg); //1.成功完成模态框 $("#addEmpModal").modal('hide') //2.来到列表最后一页 //发送ajax请求,显示最后一页,因为插件做了参数合理化配置,可以配置一个比较大的数字 //这样,查到的总是最后一页记录,我们使用全局的总记录数 toPage(golbalTotalCount); } }); }); </script> </body> </html>
简单测试:
这样我们前端校验就到此结束!但是用户名呢不能重复,前端是操作不了这个的,我们进行后端的校验。
接下来我们进行后端员工姓名重复的后端校验!
我们通过前台发送ajax请求检查是否用户名是否可用,我们先编写相关的controller:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package cn.crud.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import cn.crud.bean.Employee; import cn.crud.bean.Msg; import cn.crud.service.EmpService; /** * 处理员工的CRUD请求 * @author Administrator * */ @Controller public class EmpController { @Autowired private EmpService empService; /** * 校验用户名是否重复,是否可用的方法 * @return 返回的是我们包装的对象 */ @RequestMapping("/vadEmpName") @ResponseBody public Msg vadEmpName(@RequestParam("empName") String empName){ boolean isRepet = empService.vadEmpName(empName); if(isRepet){ return Msg.success(); }else{ return Msg.fail(); } } /** * 处理添加员工的ajax请求的方法 * @return */ @RequestMapping(value="/emp",method=RequestMethod.POST) @ResponseBody public Msg saveEmp(Employee employee){ empService.saveEmp(employee); return Msg.success(); } /** * 分页信息的AJAX请求 * @ResponseBody可以将返回的对象转为JSON字符串 * 此注解需要引入jackson的包(以及注解驱动的配置等,这里已经进行配置) * 将返回信息包装在msg里 */ @RequestMapping("/emps") @ResponseBody public Msg getEmpsWithJson(@RequestParam(value="pn",defaultValue="1") Integer pn, Model model){ //改造为一个分页查询 //在查询之前传入分页参数:起始页和每页记录数 PageHelper.startPage(pn, 5); //后面紧跟的查询就是分页查询 List<Employee> empList = empService.getAll(); //用PageInfo对结果进行包装,只需要将PageInfo交给页面即可,这里面封装了详细的信息,第二个参数为需要连续显示的记录数 PageInfo page = new PageInfo(empList,5); //直接将pageInfo对象进行返回 //将pageInfo放在msg里进行返回,链式操作返回对象本身 return Msg.success().add("pageInfo", page); } /** * 分页查询员工数据 */ //@RequestMapping("/emps") public String getEmps(@RequestParam(value="pn",defaultValue="1") Integer pn, Model model){ //改造为一个分页查询 //在查询之前传入分页参数:起始页和每页记录数 PageHelper.startPage(pn, 5); //后面紧跟的查询就是分页查询 List<Employee> empList = empService.getAll(); //用PageInfo对结果进行包装,只需要将PageInfo交给页面即可,这里面封装了详细的信息,第二个参数为需要连续显示的记录数 PageInfo page = new PageInfo(empList,5); model.addAttribute("pageInfo", page); return "list"; } }
这里注意相关的service是如何实现的:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package cn.crud.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import cn.crud.bean.Employee; import cn.crud.bean.EmployeeExample; import cn.crud.bean.EmployeeExample.Criteria; import cn.crud.dao.EmployeeMapper; /** * 处理员工的service * @author Administrator * */ @Service public class EmpService { @Autowired private EmployeeMapper employeeMapper; /** * 查询所有员工 * @return */ public List<Employee> getAll() { /** * 没有查询条件的查询所有,带部门信息 */ return employeeMapper.selectByExampleWithDept(null); } /** * 增加员工 * @param employee */ public void saveEmp(Employee employee) { //我们选择有选择的保存,因为ID是自增的 employeeMapper.insertSelective(employee); } /** * 检验用户名是否可用 * @param empName * @return */ public boolean vadEmpName(String empName) { /*按要求统计符合条件记录数,返回一个整数*/ //构建example EmployeeExample example = new EmployeeExample(); //构建查询条件 criteria Criteria criteria = example.createCriteria(); //构建条件 criteria.andEmpNameEqualTo(empName); //返回符合条件的记录数,==0时可用 long count = employeeMapper.countByExample(example); return count == 0; } }
前台就相应的完成:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!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>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <!-- 员工新增模态框 --> <div class="modal fade" id="addEmpModal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span>×</span></button> <h4 class="modal-title" id="myModalLabel">添加员工</h4> </div> <div class="modal-body"> <form class="form-horizontal"> <!-- 输入员工姓名 --> <div class="form-group"> <label for="input_empName" class="col-sm-2 control-label">empName</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="input_empName" placeholder="empName"> <span class="help-block"></span> </div> </div> <!-- 输入员工邮箱 --> <div class="form-group"> <label for="input_email" class="col-sm-2 control-label">email</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="input_email" placeholder="email"> <span class="help-block"></span> </div> </div> <!-- 选择员工性别 --> <div class="form-group"> <label class="col-sm-2 control-label">gender</label> <div class="col-sm-2"> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="M" checked> 男 </label> </div> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="F"> 女 </label> </div> </div> </div> <!-- 部门名称 --> <div class="form-group"> <label class="col-sm-2 control-label">deptName</label> <div class="col-sm-4" style="width:120px"> <!-- 部门名称是变动的,这里保存员工是只保存ID的形式 --> <select class="form-control" name="dId"> </select> </div> </div> </form> </div> <!-- 页脚按钮操作 --> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="emp_saveBtn">保存</button> </div> </div> </div> </div> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary" id="addBtn_modal">新增</button> <button type="button" class="btn btn-danger ">删除</button> </div> </div> <!-- 表格 --> <div class="row"> <div class="col-md-12"> <table class="table table-hover" id="emps_table"> <thead> <tr> <th>#</th> <th>empName</th> <th>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //全局总记录数,用于查最后一页 var golbalTotalCount; //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //清空表格数据 $("#emps_table tbody").empty(); //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(emailTd) .append(genderTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //清空分页数据 $("#page_info").empty(); //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; //给全局记录数赋值 golbalTotalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //清空分页导航信息 $("#page_nav").empty(); //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); }else{ //添加首页和前一页翻页的单机事件 firstPageLi.click(function(){ toPage(1); }); prePageLi.click(function(){ toPage(result.map.pageInfo.pageNum-1); }); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); }else{ //添加末页和后一页翻页的单机事件 lastPageLi.click(function(){ toPage(result.map.pageInfo.pages); }); nextPageLi.click(function(){ toPage(result.map.pageInfo.pageNum+1); }); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); //li加入ul,ul加入nav navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } //增加员工的事件 $("#addBtn_modal").click(function(){ //发送ajax请求查询部门信息 getDepts(); //弹出模态框 $('#addEmpModal').modal({ backdrop:false }); }); //得到部门信息的函数 function getDepts(){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/depts", //请求要带的数据,这里无需带数据 //请求成功的回调函数 success : function(result) { $.each(result.map.deptList,function(){ //这里换用不传参的方式,采用this引用正在遍历的对象 var optionEle = $("<option></option>").append(this.deptName).attr("value",this.deptId); optionEle.appendTo("#addEmpModal select"); }); } }); } //添加表单数据的前段校验 function validate_add_form(){ //1.获取需要校验的值 //2.使用jQuery正则(api中常用正则)进行校验(校验插件的使用待更新) var empNameVal = $("#input_empName").val(); //校验的正则表达式(可以搜索常用正则) var regName = /(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5}$)/; //开始校验用户名 if(!regName.test(empNameVal)){ //alert("用户名只能是6-16位英文数字或2-5位汉字组合!"); //将提示信息优化,使用bootstrap的样式,给父元素添加相应的类即可 vilidate_form("#input_empName","error","用户名只能是6-16位英文数字或2-5位汉字组合!"); //$("#input_empName").parent().addClass("has-error"); //$("#input_empName").next(".help-block").text("用户名只能是6-16位英文数字或2-5位汉字组合!"); return false; }else{ vilidate_form("#input_empName","success","用户名正确!"); //$("#input_empName").parent().addClass("has-success"); //$("#input_empName").next(".help-block").text("用户名正确!"); } //同理,校验邮箱 var empEmailVal = $("#input_email").val(); var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/; //开始校验邮箱 if(!regEmail.test(empEmailVal)){ //alert("邮箱不合法!"); vilidate_form("#input_email","error","邮箱不合法!"); //$("#input_email").parent().addClass("has-error"); //$("#input_email").next(".help-block").text("邮箱不合法!"); return false; }else{ vilidate_form("#input_email","success","邮箱格式正确!"); //$("#input_email").parent().addClass("has-success"); //$("#input_email").next(".help-block").text("邮箱格式正确!"); } return true; } //重新抽取校验函数完成之前重复样式的清除工作 function vilidate_form(ele,status,msg){ //清除当前校验状态 $(ele).parent().removeClass("has-success has-error"); $(ele).next(".help-block").text(""); if("success" == status){ $(ele).parent().addClass("has-success"); $(ele).next(".help-block").text(msg); }else if("error" == status){ $(ele).parent().addClass("has-error"); $(ele).next(".help-block").text(msg); } } //为添加员工姓名输入框添加change事件,完成用户名重复的后端校验 $("#input_empName").change(function(){ //发送ajax请求,查询用户名是否重复 var empName = this.value; $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/vadEmpName", //请求要带的数据 data:"empName="+empName, //请求成功的回调函数 success : function(result) { if(result.code == 100){//成功,用户名可用 vilidate_form("#input_empName","success","用户名可用!"); }else{//失败,用户名不可用 vilidate_form("#input_empName","error","用户名已被占用!"); } } }); }); //为添加员工的保存按钮绑定单击事件 $("#emp_saveBtn").click(function(){ //1.进行表单数据的校验 if(!validate_add_form()){ return false; } //2.模态框中保存按钮发送ajax请求 $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/emp", //请求要带的数据,这里是模态框中的值, //这里应该采用的是jQuery的序列化表单的方法进行提取表单数据,serialize(); //表单序列化的数据:$("#addEmpModal form").serialize(); data:$("#addEmpModal form").serialize(), //请求成功的回调函数 success : function(result) { //alert(result.msg); //1.成功完成模态框 $("#addEmpModal").modal('hide') //2.来到列表最后一页 //发送ajax请求,显示最后一页,因为插件做了参数合理化配置,可以配置一个比较大的数字 //这样,查到的总是最后一页记录,我们使用全局的总记录数 toPage(golbalTotalCount); } }); }); </script> </body> </html>
简单测试:
当然,这里会有个问题,即使用户名被占用了,只要邮箱正确,依旧可以保存!我们查看我们的代码可以发现,我们校验后只是进行了提示信息的显示,我们需要进行改善:
这里我们可以将被占用的校验结果进行保存,然后用这个结果去禁用保存按钮,失败则使得按钮无法生效!
这里采用的方式是给按钮添加自定义属性,再进行自定义属性的内容校验:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!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>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <!-- 员工新增模态框 --> <div class="modal fade" id="addEmpModal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span>×</span></button> <h4 class="modal-title" id="myModalLabel">添加员工</h4> </div> <div class="modal-body"> <form class="form-horizontal"> <!-- 输入员工姓名 --> <div class="form-group"> <label for="input_empName" class="col-sm-2 control-label">empName</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="input_empName" placeholder="empName"> <span class="help-block"></span> </div> </div> <!-- 输入员工邮箱 --> <div class="form-group"> <label for="input_email" class="col-sm-2 control-label">email</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="input_email" placeholder="email"> <span class="help-block"></span> </div> </div> <!-- 选择员工性别 --> <div class="form-group"> <label class="col-sm-2 control-label">gender</label> <div class="col-sm-2"> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="M" checked> 男 </label> </div> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="F"> 女 </label> </div> </div> </div> <!-- 部门名称 --> <div class="form-group"> <label class="col-sm-2 control-label">deptName</label> <div class="col-sm-4" style="width:120px"> <!-- 部门名称是变动的,这里保存员工是只保存ID的形式 --> <select class="form-control" name="dId"> </select> </div> </div> </form> </div> <!-- 页脚按钮操作 --> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="emp_saveBtn">保存</button> </div> </div> </div> </div> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary" id="addBtn_modal">新增</button> <button type="button" class="btn btn-danger ">删除</button> </div> </div> <!-- 表格 --> <div class="row"> <div class="col-md-12"> <table class="table table-hover" id="emps_table"> <thead> <tr> <th>#</th> <th>empName</th> <th>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //全局总记录数,用于查最后一页 var golbalTotalCount; //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //清空表格数据 $("#emps_table tbody").empty(); //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(emailTd) .append(genderTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //清空分页数据 $("#page_info").empty(); //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; //给全局记录数赋值 golbalTotalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //清空分页导航信息 $("#page_nav").empty(); //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); }else{ //添加首页和前一页翻页的单机事件 firstPageLi.click(function(){ toPage(1); }); prePageLi.click(function(){ toPage(result.map.pageInfo.pageNum-1); }); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); }else{ //添加末页和后一页翻页的单机事件 lastPageLi.click(function(){ toPage(result.map.pageInfo.pages); }); nextPageLi.click(function(){ toPage(result.map.pageInfo.pageNum+1); }); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); //li加入ul,ul加入nav navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } //增加员工的事件 $("#addBtn_modal").click(function(){ //发送ajax请求查询部门信息 getDepts(); //弹出模态框 $('#addEmpModal').modal({ backdrop:false }); }); //得到部门信息的函数 function getDepts(){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/depts", //请求要带的数据,这里无需带数据 //请求成功的回调函数 success : function(result) { $.each(result.map.deptList,function(){ //这里换用不传参的方式,采用this引用正在遍历的对象 var optionEle = $("<option></option>").append(this.deptName).attr("value",this.deptId); optionEle.appendTo("#addEmpModal select"); }); } }); } //添加表单数据的前段校验 function validate_add_form(){ //1.获取需要校验的值 //2.使用jQuery正则(api中常用正则)进行校验(校验插件的使用待更新) var empNameVal = $("#input_empName").val(); //校验的正则表达式(可以搜索常用正则) var regName = /(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5}$)/; //开始校验用户名 if(!regName.test(empNameVal)){ //alert("用户名只能是6-16位英文数字或2-5位汉字组合!"); //将提示信息优化,使用bootstrap的样式,给父元素添加相应的类即可 vilidate_form("#input_empName","error","用户名只能是6-16位英文数字或2-5位汉字组合!"); //$("#input_empName").parent().addClass("has-error"); //$("#input_empName").next(".help-block").text("用户名只能是6-16位英文数字或2-5位汉字组合!"); return false; }else{ vilidate_form("#input_empName","success","用户名正确!"); //$("#input_empName").parent().addClass("has-success"); //$("#input_empName").next(".help-block").text("用户名正确!"); } //同理,校验邮箱 var empEmailVal = $("#input_email").val(); var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/; //开始校验邮箱 if(!regEmail.test(empEmailVal)){ //alert("邮箱不合法!"); vilidate_form("#input_email","error","邮箱不合法!"); //$("#input_email").parent().addClass("has-error"); //$("#input_email").next(".help-block").text("邮箱不合法!"); return false; }else{ vilidate_form("#input_email","success","邮箱格式正确!"); //$("#input_email").parent().addClass("has-success"); //$("#input_email").next(".help-block").text("邮箱格式正确!"); } return true; } //重新抽取校验函数完成之前重复样式的清除工作 function vilidate_form(ele,status,msg){ //清除当前校验状态 $(ele).parent().removeClass("has-success has-error"); $(ele).next(".help-block").text(""); if("success" == status){ $(ele).parent().addClass("has-success"); $(ele).next(".help-block").text(msg); }else if("error" == status){ $(ele).parent().addClass("has-error"); $(ele).next(".help-block").text(msg); } } //为添加员工姓名输入框添加change事件,完成用户名重复的后端校验 $("#input_empName").change(function(){ //发送ajax请求,查询用户名是否重复 var empName = this.value; $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/vadEmpName", //请求要带的数据 data:"empName="+empName, //请求成功的回调函数 success : function(result) { if(result.code == 100){//成功,用户名可用 vilidate_form("#input_empName","success","用户名可用!"); $("#emp_saveBtn").attr("ajax-vad","success"); }else{//失败,用户名不可用 vilidate_form("#input_empName","error","用户名已被占用!"); $("#emp_saveBtn").attr("ajax-vad","error"); } } }); }); //为添加员工的保存按钮绑定单击事件 $("#emp_saveBtn").click(function(){ //1.5发送ajax请求之前进行用户名是否可用的校验: if($(this).attr("ajax-vad")=="error"){ return false; } //1.进行表单数据的校验 if(!validate_add_form()){ return false; } //2.模态框中保存按钮发送ajax请求 $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/emp", //请求要带的数据,这里是模态框中的值, //这里应该采用的是jQuery的序列化表单的方法进行提取表单数据,serialize(); //表单序列化的数据:$("#addEmpModal form").serialize(); data:$("#addEmpModal form").serialize(), //请求成功的回调函数 success : function(result) { //alert(result.msg); //1.成功完成模态框 $("#addEmpModal").modal('hide') //2.来到列表最后一页 //发送ajax请求,显示最后一页,因为插件做了参数合理化配置,可以配置一个比较大的数字 //这样,查到的总是最后一页记录,我们使用全局的总记录数 toPage(golbalTotalCount); } }); }); </script> </body> </html>
测试这里暂时略去
这里还有个问题是:由于我们是ajax,页面没有刷新,如果直接再次直接添加,原来输入框的内容不做修改,直接点击保存也会保存成功!
这样就造成了重复添加,原因呢是页面没有刷新,二校验用户可用的事件是change()事件,如果输入框内容没有change,而原来的内容又可以通过校验,就造成了重复添加!
我们解决方案是在添加之前进行重置,当然jQuery是没有reset方法,我们使用js的reset()方法,完成了表单的重置!:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!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>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <!-- 员工新增模态框 --> <div class="modal fade" id="addEmpModal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span>×</span></button> <h4 class="modal-title" id="myModalLabel">添加员工</h4> </div> <div class="modal-body"> <form class="form-horizontal"> <!-- 输入员工姓名 --> <div class="form-group"> <label for="input_empName" class="col-sm-2 control-label">empName</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="input_empName" placeholder="empName"> <span class="help-block"></span> </div> </div> <!-- 输入员工邮箱 --> <div class="form-group"> <label for="input_email" class="col-sm-2 control-label">email</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="input_email" placeholder="email"> <span class="help-block"></span> </div> </div> <!-- 选择员工性别 --> <div class="form-group"> <label class="col-sm-2 control-label">gender</label> <div class="col-sm-2"> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="M" checked> 男 </label> </div> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="F"> 女 </label> </div> </div> </div> <!-- 部门名称 --> <div class="form-group"> <label class="col-sm-2 control-label">deptName</label> <div class="col-sm-4" style="width:120px"> <!-- 部门名称是变动的,这里保存员工是只保存ID的形式 --> <select class="form-control" name="dId"> </select> </div> </div> </form> </div> <!-- 页脚按钮操作 --> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="emp_saveBtn">保存</button> </div> </div> </div> </div> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary" id="addBtn_modal">新增</button> <button type="button" class="btn btn-danger ">删除</button> </div> </div> <!-- 表格 --> <div class="row"> <div class="col-md-12"> <table class="table table-hover" id="emps_table"> <thead> <tr> <th>#</th> <th>empName</th> <th>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //全局总记录数,用于查最后一页 var golbalTotalCount; //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //清空表格数据 $("#emps_table tbody").empty(); //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(emailTd) .append(genderTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //清空分页数据 $("#page_info").empty(); //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; //给全局记录数赋值 golbalTotalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //清空分页导航信息 $("#page_nav").empty(); //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); }else{ //添加首页和前一页翻页的单机事件 firstPageLi.click(function(){ toPage(1); }); prePageLi.click(function(){ toPage(result.map.pageInfo.pageNum-1); }); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); }else{ //添加末页和后一页翻页的单机事件 lastPageLi.click(function(){ toPage(result.map.pageInfo.pages); }); nextPageLi.click(function(){ toPage(result.map.pageInfo.pageNum+1); }); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); //li加入ul,ul加入nav navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } //清空表单样式及内容 function reset_form(ele){ $(ele)[0].reset(); //清空表单样式 $(ele).find("*").removeClass("has-error has-success"); $(ele).find(".help-block").text(""); } //增加员工的事件,弹出员工模态框 $("#addBtn_modal").click(function(){ //重置表单: reset_form("#addEmpModal form"); //发送ajax请求查询部门信息 getDepts(); //弹出模态框 $('#addEmpModal').modal({ backdrop:false }); }); //得到部门信息的函数 function getDepts(){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/depts", //请求要带的数据,这里无需带数据 //请求成功的回调函数 success : function(result) { $.each(result.map.deptList,function(){ //这里换用不传参的方式,采用this引用正在遍历的对象 var optionEle = $("<option></option>").append(this.deptName).attr("value",this.deptId); optionEle.appendTo("#addEmpModal select"); }); } }); } //添加表单数据的前段校验 function validate_add_form(){ //1.获取需要校验的值 //2.使用jQuery正则(api中常用正则)进行校验(校验插件的使用待更新) var empNameVal = $("#input_empName").val(); //校验的正则表达式(可以搜索常用正则) var regName = /(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5}$)/; //开始校验用户名 if(!regName.test(empNameVal)){ //alert("用户名只能是6-16位英文数字或2-5位汉字组合!"); //将提示信息优化,使用bootstrap的样式,给父元素添加相应的类即可 vilidate_form("#input_empName","error","用户名只能是6-16位英文数字或2-5位汉字组合!"); //$("#input_empName").parent().addClass("has-error"); //$("#input_empName").next(".help-block").text("用户名只能是6-16位英文数字或2-5位汉字组合!"); return false; }else{ vilidate_form("#input_empName","success","用户名正确!"); //$("#input_empName").parent().addClass("has-success"); //$("#input_empName").next(".help-block").text("用户名正确!"); } //同理,校验邮箱 var empEmailVal = $("#input_email").val(); var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/; //开始校验邮箱 if(!regEmail.test(empEmailVal)){ //alert("邮箱不合法!"); vilidate_form("#input_email","error","邮箱不合法!"); //$("#input_email").parent().addClass("has-error"); //$("#input_email").next(".help-block").text("邮箱不合法!"); return false; }else{ vilidate_form("#input_email","success","邮箱格式正确!"); //$("#input_email").parent().addClass("has-success"); //$("#input_email").next(".help-block").text("邮箱格式正确!"); } return true; } //重新抽取校验函数完成之前重复样式的清除工作 function vilidate_form(ele,status,msg){ //清除当前校验状态 $(ele).parent().removeClass("has-success has-error"); $(ele).next(".help-block").text(""); if("success" == status){ $(ele).parent().addClass("has-success"); $(ele).next(".help-block").text(msg); }else if("error" == status){ $(ele).parent().addClass("has-error"); $(ele).next(".help-block").text(msg); } } //为添加员工姓名输入框添加change事件,完成用户名重复的后端校验 $("#input_empName").change(function(){ //发送ajax请求,查询用户名是否重复 var empName = this.value; $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/vadEmpName", //请求要带的数据 data:"empName="+empName, //请求成功的回调函数 success : function(result) { if(result.code == 100){//成功,用户名可用 vilidate_form("#input_empName","success","用户名可用!"); $("#emp_saveBtn").attr("ajax-vad","success"); }else{//失败,用户名不可用 vilidate_form("#input_empName","error","用户名已被占用!"); $("#emp_saveBtn").attr("ajax-vad","error"); } } }); }); //为添加员工的保存按钮绑定单击事件 $("#emp_saveBtn").click(function(){ //1.5发送ajax请求之前进行用户名是否可用的校验: if($(this).attr("ajax-vad")=="error"){ return false; } //1.进行表单数据的校验 if(!validate_add_form()){ return false; } //2.模态框中保存按钮发送ajax请求 $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/emp", //请求要带的数据,这里是模态框中的值, //这里应该采用的是jQuery的序列化表单的方法进行提取表单数据,serialize(); //表单序列化的数据:$("#addEmpModal form").serialize(); data:$("#addEmpModal form").serialize(), //请求成功的回调函数 success : function(result) { //alert(result.msg); //1.成功完成模态框 $("#addEmpModal").modal('hide') //2.来到列表最后一页 //发送ajax请求,显示最后一页,因为插件做了参数合理化配置,可以配置一个比较大的数字 //这样,查到的总是最后一页记录,我们使用全局的总记录数 toPage(golbalTotalCount); } }); }); </script> </body> </html>
//再次点击新增,完成了新增前表单信息的清空
但是我们多测试几次,会发现校验逻辑会有一点问题,比如前面提示用户名可用(不重复),后面提交时又会出现格式不正确,造成校验信息的混乱!我们再次完善:
解决方案是让前后台统一校验顺序与规则,当格式不正确时不进行重复性校验:
前台完成表单内容和样式的移除,以及后台校验回来的校验信息的更改:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!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>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <!-- 员工新增模态框 --> <div class="modal fade" id="addEmpModal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span>×</span></button> <h4 class="modal-title" id="myModalLabel">添加员工</h4> </div> <div class="modal-body"> <form class="form-horizontal"> <!-- 输入员工姓名 --> <div class="form-group"> <label for="input_empName" class="col-sm-2 control-label">empName</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="input_empName" placeholder="empName"> <span class="help-block"></span> </div> </div> <!-- 输入员工邮箱 --> <div class="form-group"> <label for="input_email" class="col-sm-2 control-label">email</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="input_email" placeholder="email"> <span class="help-block"></span> </div> </div> <!-- 选择员工性别 --> <div class="form-group"> <label class="col-sm-2 control-label">gender</label> <div class="col-sm-2"> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="M" checked> 男 </label> </div> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="F"> 女 </label> </div> </div> </div> <!-- 部门名称 --> <div class="form-group"> <label class="col-sm-2 control-label">deptName</label> <div class="col-sm-4" style="width:120px"> <!-- 部门名称是变动的,这里保存员工是只保存ID的形式 --> <select class="form-control" name="dId"> </select> </div> </div> </form> </div> <!-- 页脚按钮操作 --> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="emp_saveBtn">保存</button> </div> </div> </div> </div> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary" id="addBtn_modal">新增</button> <button type="button" class="btn btn-danger ">删除</button> </div> </div> <!-- 表格 --> <div class="row"> <div class="col-md-12"> <table class="table table-hover" id="emps_table"> <thead> <tr> <th>#</th> <th>empName</th> <th>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //全局总记录数,用于查最后一页 var golbalTotalCount; //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //清空表格数据 $("#emps_table tbody").empty(); //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(emailTd) .append(genderTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //清空分页数据 $("#page_info").empty(); //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; //给全局记录数赋值 golbalTotalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //清空分页导航信息 $("#page_nav").empty(); //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); }else{ //添加首页和前一页翻页的单机事件 firstPageLi.click(function(){ toPage(1); }); prePageLi.click(function(){ toPage(result.map.pageInfo.pageNum-1); }); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); }else{ //添加末页和后一页翻页的单机事件 lastPageLi.click(function(){ toPage(result.map.pageInfo.pages); }); nextPageLi.click(function(){ toPage(result.map.pageInfo.pageNum+1); }); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); //li加入ul,ul加入nav navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } //清空表单样式及内容 function reset_form(ele){ $(ele)[0].reset(); //清空表单样式 $(ele).find("*").removeClass("has-error has-success"); $(ele).find(".help-block").text(""); } //增加员工的事件,弹出员工模态框 $("#addBtn_modal").click(function(){ //重置表单: reset_form("#addEmpModal form"); //发送ajax请求查询部门信息 getDepts(); //弹出模态框 $('#addEmpModal').modal({ backdrop:false }); }); //得到部门信息的函数 function getDepts(){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/depts", //请求要带的数据,这里无需带数据 //请求成功的回调函数 success : function(result) { $.each(result.map.deptList,function(){ //这里换用不传参的方式,采用this引用正在遍历的对象 var optionEle = $("<option></option>").append(this.deptName).attr("value",this.deptId); optionEle.appendTo("#addEmpModal select"); }); } }); } //添加表单数据的前段校验 function validate_add_form(){ //1.获取需要校验的值 //2.使用jQuery正则(api中常用正则)进行校验(校验插件的使用待更新) var empNameVal = $("#input_empName").val(); //校验的正则表达式(可以搜索常用正则) var regName = /(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5}$)/; //开始校验用户名 if(!regName.test(empNameVal)){ //alert("用户名只能是6-16位英文数字或2-5位汉字组合!"); //将提示信息优化,使用bootstrap的样式,给父元素添加相应的类即可 vilidate_form("#input_empName","error","用户名只能是6-16位英文数字或2-5位汉字组合!"); //$("#input_empName").parent().addClass("has-error"); //$("#input_empName").next(".help-block").text("用户名只能是6-16位英文数字或2-5位汉字组合!"); return false; }else{ vilidate_form("#input_empName","success","用户名正确!"); //$("#input_empName").parent().addClass("has-success"); //$("#input_empName").next(".help-block").text("用户名正确!"); } //同理,校验邮箱 var empEmailVal = $("#input_email").val(); var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/; //开始校验邮箱 if(!regEmail.test(empEmailVal)){ //alert("邮箱不合法!"); vilidate_form("#input_email","error","邮箱不合法!"); //$("#input_email").parent().addClass("has-error"); //$("#input_email").next(".help-block").text("邮箱不合法!"); return false; }else{ vilidate_form("#input_email","success","邮箱格式正确!"); //$("#input_email").parent().addClass("has-success"); //$("#input_email").next(".help-block").text("邮箱格式正确!"); } return true; } //重新抽取校验函数完成之前重复样式的清除工作 function vilidate_form(ele,status,msg){ //清除当前校验状态 $(ele).parent().removeClass("has-success has-error"); $(ele).next(".help-block").text(""); if("success" == status){ $(ele).parent().addClass("has-success"); $(ele).next(".help-block").text(msg); }else if("error" == status){ $(ele).parent().addClass("has-error"); $(ele).next(".help-block").text(msg); } } //为添加员工姓名输入框添加change事件,完成用户名重复的后端校验 $("#input_empName").change(function(){ //发送ajax请求,查询用户名是否重复 var empName = this.value; $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/vadEmpName", //请求要带的数据 data:"empName="+empName, //请求成功的回调函数 success : function(result) { if(result.code == 100){//成功,用户名可用 vilidate_form("#input_empName","success","用户名可用!"); $("#emp_saveBtn").attr("ajax-vad","success"); }else{//失败,用户名不可用 vilidate_form("#input_empName","error",result.map.vadFailMeg); $("#emp_saveBtn").attr("ajax-vad","error"); } } }); }); //为添加员工的保存按钮绑定单击事件 $("#emp_saveBtn").click(function(){ //1.5发送ajax请求之前进行用户名是否可用的校验: if($(this).attr("ajax-vad")=="error"){ return false; } //1.进行表单数据的校验 if(!validate_add_form()){ return false; } //2.模态框中保存按钮发送ajax请求 $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/emp", //请求要带的数据,这里是模态框中的值, //这里应该采用的是jQuery的序列化表单的方法进行提取表单数据,serialize(); //表单序列化的数据:$("#addEmpModal form").serialize(); data:$("#addEmpModal form").serialize(), //请求成功的回调函数 success : function(result) { //alert(result.msg); //1.成功完成模态框 $("#addEmpModal").modal('hide') //2.来到列表最后一页 //发送ajax请求,显示最后一页,因为插件做了参数合理化配置,可以配置一个比较大的数字 //这样,查到的总是最后一页记录,我们使用全局的总记录数 toPage(golbalTotalCount); } }); }); </script> </body> </html>
后台校验加格式的校验和错误信息:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package cn.crud.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import cn.crud.bean.Employee; import cn.crud.bean.Msg; import cn.crud.service.EmpService; /** * 处理员工的CRUD请求 * @author Administrator * */ @Controller public class EmpController { @Autowired private EmpService empService; /** * 校验用户名是否重复,是否可用的方法 * @return 返回的是我们包装的对象 */ @RequestMapping("/vadEmpName") @ResponseBody public Msg vadEmpName(@RequestParam("empName") String empName){ //在判断是否重复之前,先进行格式是否正确的校验 //校验的正则表达式(可以搜索常用正则) //特别注意这里的正则和js的正则不一样,加 / 包裹的是js的写法 String regName = "(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5}$)"; boolean b = empName.matches(regName); if(!b){ return Msg.fail().add("vadFailMeg", "用户名格式错误!"); } //后端用户名重复性校验 boolean isRepet = empService.vadEmpName(empName); if(isRepet){ return Msg.success(); }else{ return Msg.fail().add("vadFailMeg", "用户名已被占用!"); } } /** * 处理添加员工的ajax请求的方法 * @return */ @RequestMapping(value="/emp",method=RequestMethod.POST) @ResponseBody public Msg saveEmp(Employee employee){ empService.saveEmp(employee); return Msg.success(); } /** * 分页信息的AJAX请求 * @ResponseBody可以将返回的对象转为JSON字符串 * 此注解需要引入jackson的包(以及注解驱动的配置等,这里已经进行配置) * 将返回信息包装在msg里 */ @RequestMapping("/emps") @ResponseBody public Msg getEmpsWithJson(@RequestParam(value="pn",defaultValue="1") Integer pn, Model model){ //改造为一个分页查询 //在查询之前传入分页参数:起始页和每页记录数 PageHelper.startPage(pn, 5); //后面紧跟的查询就是分页查询 List<Employee> empList = empService.getAll(); //用PageInfo对结果进行包装,只需要将PageInfo交给页面即可,这里面封装了详细的信息,第二个参数为需要连续显示的记录数 PageInfo page = new PageInfo(empList,5); //直接将pageInfo对象进行返回 //将pageInfo放在msg里进行返回,链式操作返回对象本身 return Msg.success().add("pageInfo", page); } /** * 分页查询员工数据 */ //@RequestMapping("/emps") public String getEmps(@RequestParam(value="pn",defaultValue="1") Integer pn, Model model){ //改造为一个分页查询 //在查询之前传入分页参数:起始页和每页记录数 PageHelper.startPage(pn, 5); //后面紧跟的查询就是分页查询 List<Employee> empList = empService.getAll(); //用PageInfo对结果进行包装,只需要将PageInfo交给页面即可,这里面封装了详细的信息,第二个参数为需要连续显示的记录数 PageInfo page = new PageInfo(empList,5); model.addAttribute("pageInfo", page); return "list"; } }
测试这里就暂时略去。
到这里,前端校验就暂时告一段落,其实我们可以发现,前端校验是给不做坏事的用户的温馨的提示的,但是如果有人捣蛋,通过伪装一些参数,通过查看源代码,修改相关的样式甚至是禁用一些JS就可以跳过一些前端的校验,也就是说,前端校验是防君子不妨小人。这里,我们开始引入正式的后端校验:JSR303后端校验!
关于JSR303的校验这里不详细展开,暂时只做简单介绍:
1.要支持JSR303,需要导入hibernate-validator的包(JSR303的一个实现)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.4.1.Final</version> </dependency>
2.在实体类上加上相应的注解(详细API请查看官网文档)
Employee实体类:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package cn.crud.bean; import javax.validation.constraints.Pattern; public class Employee { public Employee() { super(); } public Employee(Integer empId, String empName, String gender, String email, Integer dId) { super(); this.empId = empId; this.empName = empName; this.gender = gender; this.email = email; this.dId = dId; } private Integer empId; /*使用JSR303完成后端校验*/ //使用自定义校验正则表达式 @Pattern(regexp="(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5}$)" ,message="用户名只能是6-16位英文数字或2-5位汉字组合!") private String empName; private String gender; //可以使用JSR的email校验,@Email //这里特别注意正则表达式的写法,遇到真正要用\时需要双 \\ @Pattern(regexp="^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$" ,message="邮箱格式不正确") private String email; private Integer dId; private Department department; public Integer getEmpId() { return empId; } public void setEmpId(Integer empId) { this.empId = empId; } public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName == null ? null : empName.trim(); } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender == null ? null : gender.trim(); } public String getEmail() { return email; } public void setEmail(String email) { this.email = email == null ? null : email.trim(); } public Integer getdId() { return dId; } public void setdId(Integer dId) { this.dId = dId; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } }
3.如何使用?在相关的方法入参使用对应的注解:我们看保存方法的后端校验
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package cn.crud.controller; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import cn.crud.bean.Employee; import cn.crud.bean.Msg; import cn.crud.service.EmpService; /** * 处理员工的CRUD请求 * @author Administrator * */ @Controller public class EmpController { @Autowired private EmpService empService; /** * 校验用户名是否重复,是否可用的方法 * @return 返回的是我们包装的对象 */ @RequestMapping("/vadEmpName") @ResponseBody public Msg vadEmpName(@RequestParam("empName") String empName){ //在判断是否重复之前,先进行格式是否正确的校验 //校验的正则表达式(可以搜索常用正则) //特别注意这里的正则和js的正则不一样,加 / 包裹的是js的写法 String regName = "(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5}$)"; boolean b = empName.matches(regName); if(!b){ return Msg.fail().add("vadFailMeg", "用户名格式错误!"); } //后端用户名重复性校验 boolean isRepet = empService.vadEmpName(empName); if(isRepet){ return Msg.success(); }else{ return Msg.fail().add("vadFailMeg", "用户名已被占用!"); } } /** * 处理添加员工的ajax请求的方法 * 1.要支持JSR303后端校验,需要导入hibernate-validate的包 * 2.在bean的属性中添加相关的注解 * 3.在方法入参添加相关的注解 * @Valid后跟需要校验的对象,BindingResult时校验的结果 * @return */ @RequestMapping(value="/emp",method=RequestMethod.POST) @ResponseBody public Msg saveEmp(@Valid Employee employee,BindingResult result){ if(result.hasErrors()){//若存在错误,校验失败 //保存错误信息的map,便于封装 Map<String,Object> errors = new HashMap<String,Object>(); //返回错误信息 List<FieldError> fieldErrors = result.getFieldErrors(); for (FieldError fieldError : fieldErrors) {//遍历错误信息 //错误的字段名: System.out.println("错误的字段名:"+fieldError.getField()); //错误的提示信息 System.out.println("错误信息:"+fieldError.getDefaultMessage()); //封装错误信息 errors.put(fieldError.getField(), fieldError.getDefaultMessage()); } //最后封装如Msg的map中进行返回 return Msg.fail().add("fieldErrors", errors); }else{ empService.saveEmp(employee); return Msg.success(); } } /** * 分页信息的AJAX请求 * @ResponseBody可以将返回的对象转为JSON字符串 * 此注解需要引入jackson的包(以及注解驱动的配置等,这里已经进行配置) * 将返回信息包装在msg里 */ @RequestMapping("/emps") @ResponseBody public Msg getEmpsWithJson(@RequestParam(value="pn",defaultValue="1") Integer pn, Model model){ //改造为一个分页查询 //在查询之前传入分页参数:起始页和每页记录数 PageHelper.startPage(pn, 5); //后面紧跟的查询就是分页查询 List<Employee> empList = empService.getAll(); //用PageInfo对结果进行包装,只需要将PageInfo交给页面即可,这里面封装了详细的信息,第二个参数为需要连续显示的记录数 PageInfo page = new PageInfo(empList,5); //直接将pageInfo对象进行返回 //将pageInfo放在msg里进行返回,链式操作返回对象本身 return Msg.success().add("pageInfo", page); } /** * 分页查询员工数据 */ //@RequestMapping("/emps") public String getEmps(@RequestParam(value="pn",defaultValue="1") Integer pn, Model model){ //改造为一个分页查询 //在查询之前传入分页参数:起始页和每页记录数 PageHelper.startPage(pn, 5); //后面紧跟的查询就是分页查询 List<Employee> empList = empService.getAll(); //用PageInfo对结果进行包装,只需要将PageInfo交给页面即可,这里面封装了详细的信息,第二个参数为需要连续显示的记录数 PageInfo page = new PageInfo(empList,5); model.addAttribute("pageInfo", page); return "list"; } }
4.在前端使用校验信息:在保存的操作中进行
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!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>员工列表</title> <% pageContext.setAttribute("path",request.getContextPath()); %> <!-- 推荐以 / 开始的相对路径(以服务器的根路径为相对路径) --> <link href="${path}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- 先引入jQuery,再引入js --> <script type="text/javascript" src="${path}/static/bootstrap/js/jquery.min.js"> </script> <script src="${path}/static/bootstrap/js/bootstrap.min.js"></script> </head> <body> <!-- 员工新增模态框 --> <div class="modal fade" id="addEmpModal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span>×</span></button> <h4 class="modal-title" id="myModalLabel">添加员工</h4> </div> <div class="modal-body"> <form class="form-horizontal"> <!-- 输入员工姓名 --> <div class="form-group"> <label for="input_empName" class="col-sm-2 control-label">empName</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="input_empName" placeholder="empName"> <span class="help-block"></span> </div> </div> <!-- 输入员工邮箱 --> <div class="form-group"> <label for="input_email" class="col-sm-2 control-label">email</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="input_email" placeholder="email"> <span class="help-block"></span> </div> </div> <!-- 选择员工性别 --> <div class="form-group"> <label class="col-sm-2 control-label">gender</label> <div class="col-sm-2"> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="M" checked> 男 </label> </div> <div class="radio"> <label> <input type="radio" name="gender" id="input_gender" value="F"> 女 </label> </div> </div> </div> <!-- 部门名称 --> <div class="form-group"> <label class="col-sm-2 control-label">deptName</label> <div class="col-sm-4" style="width:120px"> <!-- 部门名称是变动的,这里保存员工是只保存ID的形式 --> <select class="form-control" name="dId"> </select> </div> </div> </form> </div> <!-- 页脚按钮操作 --> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="emp_saveBtn">保存</button> </div> </div> </div> </div> <div class="container"> <!-- 分为四大行 --> <!-- 标题 --> <div class="row"> <div class="col-md-12"> <font size="20">SSM-CRUD</font> </div> </div> <!-- 按钮 --> <div class="row"> <!-- 偏移4列 --> <div class="col-md-4 col-md-offset-8"> <button type="button" class="btn btn-primary" id="addBtn_modal">新增</button> <button type="button" class="btn btn-danger ">删除</button> </div> </div> <!-- 表格 --> <div class="row"> <div class="col-md-12"> <table class="table table-hover" id="emps_table"> <thead> <tr> <th>#</th> <th>empName</th> <th>empEmail</th> <th>gender</th> <th>deptName</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 分页信息 --> <div class="row"> <!-- 分页文字信息,其中分页信息都封装在pageInfo中 --> <div class="col-md-6" id="page_info"> </div> <!-- 分页条 --> <div class="col-md-6" id="page_nav"> </div> </div> </div> <script type="text/javascript"> //全局总记录数,用于查最后一页 var golbalTotalCount; //页面加载完成后直接发送ajax请求,取得分页数据 $(function(){ //加载完页面就通过这个函数发ajax请求 toPage(1); }); //跳转到某页的函数 function toPage(pn){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/emps", //请求要带的数据 data :"pn="+pn, //请求成功的回调函数 success : function(result) { //1.解析JSON返回员工数据 build_emps_table(result); //2.解析生成分页信息(分页条与分页导航) build_pages_info(result); build_pages_nav(result); } }); } //解析员工数据 function build_emps_table(result){ //清空表格数据 $("#emps_table tbody").empty(); //员工数据 var emps = result.map.pageInfo.list; //使用jQuery遍历数组,遍历的是取出来的json数组,可以通过开发工具查看JSON结构 $.each(emps,function(idx,item){ //使用jQuery生成各列 var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); //三目运算符处理性别 var genderTd = $("<td></td>").append(item.gender=="M"?"男":"女"); var emailTd = $("<td></td>").append(item.email); var deptNameTd = $("<td></td>").append(item.department.deptName); //添加操作按钮,通过jQuery的一些操作(例如CSS的追加CSS操作),完成按钮的构建 var editBtn = $("<button></button>").addClass("btn btn-info btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")) .append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm") .append($("<span></span>").addClass("glyphicon glyphicon-trash")) .append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //链式操作完成列的添加(链式操作由于jQuery返回的是原元素) $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(emailTd) .append(genderTd) .append(deptNameTd) .append(btnTd) .appendTo($("#emps_table tbody")); }); } //生成分页信息 function build_pages_info(result){ //清空分页数据 $("#page_info").empty(); //当前页 var currentPage = result.map.pageInfo.pageNum; //总页数 var totalPage = result.map.pageInfo.pages; //总记录数 var totalCount = result.map.pageInfo.total; //给全局记录数赋值 golbalTotalCount = result.map.pageInfo.total; $("#page_info").append("当前第:"+currentPage+"页,"+"总共:"+totalPage+"页,"+"总共:"+totalCount+"条记录"); } //生成分页导航信息 function build_pages_nav(result){ //清空分页导航信息 $("#page_nav").empty(); //导航条外层的Ul var navUl = $("<ul></ul>").addClass("pagination"); //首页 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); //前一页 var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有首页 if(result.map.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); }else{ //添加首页和前一页翻页的单机事件 firstPageLi.click(function(){ toPage(1); }); prePageLi.click(function(){ toPage(result.map.pageInfo.pageNum-1); }); } //后一页 var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); //末页 var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //判断是否有末页 if(result.map.pageInfo.hasNextPage == false){ lastPageLi.addClass("disabled"); nextPageLi.addClass("disabled"); }else{ //添加末页和后一页翻页的单机事件 lastPageLi.click(function(){ toPage(result.map.pageInfo.pages); }); nextPageLi.click(function(){ toPage(result.map.pageInfo.pageNum+1); }); } //添加到ul navUl.append(firstPageLi).append(prePageLi); //遍历页码数 $.each(result.map.pageInfo.navigatepageNums,function(idx,item){ var numLi = $("<li></li>").append($("<a></a>").append(item)); //如果当前页为正在遍历的页,则高亮显示,采用增加类的方法完成 if(result.map.pageInfo.pageNum == item){ numLi.addClass("active"); } //给每个页码添加单击绑定事件 numLi.click(function(){ toPage(item); }); navUl.append(numLi); }); //li加入ul,ul加入nav navUl.append(nextPageLi).append(lastPageLi); var navEle = $("<nav></nav>").append(navUl); $("#page_nav").append(navEle); } //清空表单样式及内容 function reset_form(ele){ $(ele)[0].reset(); //清空表单样式 $(ele).find("*").removeClass("has-error has-success"); $(ele).find(".help-block").text(""); } //增加员工的事件,弹出员工模态框 $("#addBtn_modal").click(function(){ //重置表单: reset_form("#addEmpModal form"); //发送ajax请求查询部门信息 getDepts(); //弹出模态框 $('#addEmpModal').modal({ backdrop:false }); }); //得到部门信息的函数 function getDepts(){ $.ajax({ //请求方式 type : "GET", //请求url url : "${path}/depts", //请求要带的数据,这里无需带数据 //请求成功的回调函数 success : function(result) { $.each(result.map.deptList,function(){ //这里换用不传参的方式,采用this引用正在遍历的对象 var optionEle = $("<option></option>").append(this.deptName).attr("value",this.deptId); optionEle.appendTo("#addEmpModal select"); }); } }); } //添加表单数据的前段校验 function validate_add_form(){ //1.获取需要校验的值 //2.使用jQuery正则(api中常用正则)进行校验(校验插件的使用待更新) var empNameVal = $("#input_empName").val(); //校验的正则表达式(可以搜索常用正则) var regName = /(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5}$)/; //开始校验用户名 if(!regName.test(empNameVal)){ //alert("用户名只能是6-16位英文数字或2-5位汉字组合!"); //将提示信息优化,使用bootstrap的样式,给父元素添加相应的类即可 vilidate_form("#input_empName","error","用户名只能是6-16位英文数字或2-5位汉字组合!"); //$("#input_empName").parent().addClass("has-error"); //$("#input_empName").next(".help-block").text("用户名只能是6-16位英文数字或2-5位汉字组合!"); return false; }else{ vilidate_form("#input_empName","success","用户名正确!"); //$("#input_empName").parent().addClass("has-success"); //$("#input_empName").next(".help-block").text("用户名正确!"); } //同理,校验邮箱 var empEmailVal = $("#input_email").val(); var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/; //开始校验邮箱 if(!regEmail.test(empEmailVal)){ //alert("邮箱不合法!"); vilidate_form("#input_email","error","邮箱不合法!"); //$("#input_email").parent().addClass("has-error"); //$("#input_email").next(".help-block").text("邮箱不合法!"); return false; }else{ vilidate_form("#input_email","success","邮箱格式正确!"); //$("#input_email").parent().addClass("has-success"); //$("#input_email").next(".help-block").text("邮箱格式正确!"); } return true; } //重新抽取校验函数完成之前重复样式的清除工作 function vilidate_form(ele,status,msg){ //清除当前校验状态 $(ele).parent().removeClass("has-success has-error"); $(ele).next(".help-block").text(""); if("success" == status){ $(ele).parent().addClass("has-success"); $(ele).next(".help-block").text(msg); }else if("error" == status){ $(ele).parent().addClass("has-error"); $(ele).next(".help-block").text(msg); } } //为添加员工姓名输入框添加change事件,完成用户名重复的后端校验 $("#input_empName").change(function(){ //发送ajax请求,查询用户名是否重复 var empName = this.value; $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/vadEmpName", //请求要带的数据 data:"empName="+empName, //请求成功的回调函数 success : function(result) { if(result.code == 100){//成功,用户名可用 vilidate_form("#input_empName","success","用户名可用!"); $("#emp_saveBtn").attr("ajax-vad","success"); }else{//失败,用户名不可用 vilidate_form("#input_empName","error",result.map.vadFailMeg); $("#emp_saveBtn").attr("ajax-vad","error"); } } }); }); //为添加员工的保存按钮绑定单击事件 $("#emp_saveBtn").click(function(){ //1.5发送ajax请求之前进行用户名是否可用的校验: if($(this).attr("ajax-vad")=="error"){ return false; } //1.进行表单数据的校验 if(!validate_add_form()){ return false; } //2.模态框中保存按钮发送ajax请求 $.ajax({ //请求方式 type : "POST", //请求url url : "${path}/emp", //请求要带的数据,这里是模态框中的值, //这里应该采用的是jQuery的序列化表单的方法进行提取表单数据,serialize(); //表单序列化的数据:$("#addEmpModal form").serialize(); data:$("#addEmpModal form").serialize(), //请求成功的回调函数 success : function(result) { //alert(result.msg); //添加一个后端校验: if(result.code == 100){//校验成功 //1.成功完成模态框则关闭 $("#addEmpModal").modal('hide') //2.来到列表最后一页 //发送ajax请求,显示最后一页,因为插件做了参数合理化配置,可以配置一个比较大的数字 //这样,查到的总是最后一页记录,我们使用全局的总记录数 toPage(golbalTotalCount); }else{//校验失败 //console.log(result); var emailErrorMsg = result.map.fieldErrors.email; var empNameErrorMsg = result.map.fieldErrors.empName; //有哪个字段的信息就显示哪个 if(undefined != emailErrorMsg){ //显示邮箱错误信息(之前已经抽象为 方法) vilidate_form("#input_email","error",emailErrorMsg); } if(undefined != empNameErrorMsg){ //显示名称错误信息 vilidate_form("#input_empName","error",empNameErrorMsg); } } } }); }); </script> </body> </html>
至此,新增告一段落,我们接下来看修改!