删除:单个删除,多个删除,删除时候会提示是否真的要删除
逻辑:
单个删除 URI:emp/{id} DELETE
1)EmployeeController.java
/*
* 单个删除和批量删除二合一
* 思路就是传入个字符串,然后转化为Integer
* 如果是批量删除,就1-2-3
* 单个删除,就1
*/
@ResponseBody
@RequestMapping(value="/emp/{ids}",method=RequestMethod.DELETE)
public Msg deleteEmpById(@PathVariable("ids") String ids){
//传进来一个字符串,如果包含-就是批量删除,否则就是单个删除
if(ids.contains("-")){
//分割,然后封装到数组中
List<Integer> del_ids=new ArrayList<>();
String[] str_ids=ids.split("-");
//组装id的集合
for(String string:str_ids){
del_ids.add(Integer.parseInt(string));
}
employeeService.deleteBatch(del_ids);
}else{
//单个删除
Integer id=Integer.parseInt(ids);
employeeService.deleteEmp(id);
}
return Msg.success();
}
2)EmployeeService.java
//员工删除
public void deleteEmp(Integer id) {
employeeMapper.deleteByPrimaryKey(id);
}
//批量删除
public void deleteBatch(List<Integer> ids) {
EmployeeExample example=new EmployeeExample();
Criteria criteria=example.createCriteria();
//就会变成 delete from xx where emp_id in ids
criteria.andEmpIdIn(ids);
employeeMapper.deleteByExample(example);
}
index.jsp
<%@ 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("APP_PATH", request.getContextPath());
%>
<script type="text/javascript"
src="${ APP_PATH }/static/js/jquery-1.11.1.min.js"></script>
<link rel="stylesheet"
href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script
src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<!-- 员工添加的模态框,bootstrap的JavaScript插件,在<script>里写上事件 -->
<!-- Modal -->
<div class="modal fade" id="empAddModal" 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">
<!-- 从bootstrap上添加的表单模块 -->
<form class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">empName</label>
<div class="col-sm-10">
<!-- name属性可以让spring自动配置,要求就是要对应bean的属性 -->
<input type="text" class="form-control" id="empName_add_input"
placeholder="empName" name="empName"> <span
class="help-block"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">email</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="email_add_input"
placeholder="email@atguigu.com" name="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-10">
<label class="radio-inline"> <input type="radio"
name="gender" id="gender1_add_input" value="M"
checked="checked"> 男
</label> <label class="radio-inline"> <input type="radio"
name="gender" id="gender2_add_input" value="F"> 女
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">deptName</label>
<div class="col-sm-4">
<!-- 部门提交部门id即可 -->
<select class="form-control" name="dId" id="dept_add_select">
</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_save_btn">保存</button>
</div>
</div>
</div>
</div>
<!-- 员工修改的模态框 -->
<!-- Modal -->
<div class="modal fade" id="empUpdateModal" 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">员工修改</h4>
</div>
<div class="modal-body">
<!-- 从bootstrap上添加的表单模块 -->
<form class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">empName</label>
<div class="col-sm-10">
<!-- 静态控件-->
<p class="form-control-static" id="empName_update_static"></p>
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">email</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="email_update_input"
placeholder="email@atguigu.com" name="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-10">
<label class="radio-inline"> <input type="radio"
name="gender" id="gender1_update_input" value="M"
checked="checked"> 男
</label> <label class="radio-inline"> <input type="radio"
name="gender" id="gender2_update_input" value="F"> 女
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">deptName</label>
<div class="col-sm-4">
<!-- 部门提交部门id即可 -->
<select class="form-control" name="dId" id="dept_update_select">
</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_update_btn">更新</button>
</div>
</div>
</div>
</div>
<div class="container">
<!-- 标题 -->
<div class="row">
<div class="col-md-12">
<h1>SSM-CRUD</h1>
</div>
</div>
<!-- 两个按钮 -->
<div class="row">
<div class="col-md-4 col-md-offset-8">
<button class="btn btn-primary" id="emp_add_modal_btn">新增</button>
<button class="btn btn-danger" id="emp_delete_all_btn">删除</button>
</div>
</div>
<!-- 显示表格 -->
<div class="row">
<div class="col-md-12">
<table class="table table-hover" id="emps_table">
<thead>
<tr>
<th><input type="checkbox" id="check_all"></th>
<th>#</th>
<th>empName</th>
<th>gender</th>
<th>email</th>
<th>department</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- 显示分页信息 -->
<div class="row">
<!-- 分页信息 -->
<div class="col-md-6" id="page_info_area"></div>
<!-- 分页条信息 -->
<div class="col-md-6" id="page_nav_area"></div>
</div>
</div>
<script type="text/javascript">
//全员总记录数 当前页面
var totalRecord, currentPage;
/*页面加载完成后,直接发送一个ajax请求,要到分页数据*/
$(function() {
//直接去第一页
to_page(1);
});
/*==========封装方法:跳到第几页=========*/
function to_page(pn) {
$.ajax({
url : "${APP_PATH}/emps",
data : "pn=" + pn,
type : "GET",
success : function(result) {
//console.log(result);
//1、解析并显示员工数据
build_emps_table(result);
//2、解析并显示分页信息
build_page_info(result);
build_page_nav(result);
}
});
}
/*=============解析员工数据,并添加到列表下面,形成完整列表模式框架==========*/
function build_emps_table(result) {
//在构建之前,先清空,不然数据会叠加
$("#emps_table tbody").empty();
//此处要对照JSON数据,获取到员工的list
var emps = result.extend.pageInfo.list;
//jquery的遍历,emps为要遍历的参数,后面的为每次遍历返回的内容;index为下标,item为当前的数据
$
.each(
emps,
function(index, item) {
//创建列表
var checkBoxTd = $("<td><input type='checkbox' class='check_item'/></td>")
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添加bootstrap所依赖的class
var editBtn = $("<button></button>")
.addClass(
"btn btn-primary btn-sm edit_btn")
.append(
$("<span></span>")
.addClass(
"glyphicon glyphicon-pencil"))
.append("编辑");
//为编辑按钮添加一个自定义的属性,来表示当前员工的id,用于修改员工信息时候用
editBtn.attr("edit-id", item.empId);
var delBtn = $("<button></button>")
.addClass(
"btn btn-danger btn-sm delete_btn")
.append(
$("<span></span>")
.addClass(
"glyphicon glyphicon-trash"))
.append("删除");
//为删除按钮添加一个自定义的属性,来表示当前删除员工的id
delBtn.attr("del-id", item.empId);
//把两个按钮写在一起,并且在其中添加一个空格
var btnTd = $("<td></td>").append(editBtn)
.append(" ").append(delBtn);
//append方法执行完成后,还是返回原来的元素,所以可以不停使用append方法添加内容
$("<tr></tr>").append(checkBoxTd).append(
empIdTd).append(empNameTd).append(
genderTd).append(emailTd).append(
deptNameTd).append(btnTd).appendTo(
"#emps_table tbody");
});
}
/*======================解析页面左下角的信息=======================*/
function build_page_info(result) {
$("#page_info_area").empty();
//找到id=page_info_area的div块 进行操作
$("#page_info_area").append(
"当前" + result.extend.pageInfo.pageNum + "页,总共"
+ result.extend.pageInfo.pages + "页,总共"
+ result.extend.pageInfo.total + "记录");
totalRecord = result.extend.pageInfo.total;
currentPage = result.extend.pageInfo.pageNum;
}
/*===========用于解析右下角的分页条,创建分页条,并实现跳转功能=========*/
function build_page_nav(result) {
$("#page_nav_area").empty();
//此处的建议对照之前的index.jsp的html部分的代码看,不如太作死
/*开始构建 首页 末页,第一页...等元素,最后一次性加进去下面 第一段代码就完成了
<li><a href="#">首页</a></li> 这段代码
*/
var ul = $("<ul></ul>").addClass("pagination");
var firstPageLi = $("<li></li>").append(
$("<a></a>").append("首页").attr("href", "#"));
var prePageLi = $("<li></li>").append(
$("<a></a>").append("«"));
//判断能不能点击前一页或者首页
if (result.extend.pageInfo.hasPreviousPage == false) {
firstPageLi.addClass("disabled");
prePageLi.addClass("disabled");
} else {
//为元素添加点击翻页的事件
firstPageLi.click(function() {
to_page(1);
});
prePageLi.click(function() {
to_page(result.extend.pageInfo.pageNum - 1);
})
}
var nextPageLi = $("<li></li>").append(
$("<a></a>").append("»"));
var lastPageLi = $("<li></li>").append(
$("<a></a>").append("末页").attr("href", "#"));
//判断能不能点击下一页或者末页
if (result.extend.pageInfo.hasNextPage == false) {
nextPageLi.addClass("disabled");
lastPageLi.addClass("disabled");
} else {
nextPageLi.click(function() {
to_page(result.extend.pageInfo.pageNum + 1);
});
lastPageLi.click(function() {
to_page(result.extend.pageInfo.pages);
})
}
//先把首页和前一页图标加上去
ul.append(firstPageLi).append(prePageLi)
//遍历页码号 第一页第二页。。。遍历给ul中添加页码提示
$.each(result.extend.pageInfo.navigatepageNums, function(index,
item) {
var numLi = $("<li></li>").append($("<a></a>").append(item));
//让当前页面高亮
if (result.extend.pageInfo.pageNum == item) {
numLi.addClass("active");
}
//添加单击事件
numLi.click(function() {
to_page(item);
})
ul.append(numLi);
});
//最后添加后一页和末页提示
ul.append(nextPageLi).append(lastPageLi);
//把ul加入到nav元素
var navEle = $("<nav></nav>").append(ul);
navEle.appendTo("#page_nav_area");
}
/*============每次新增后,再点开新增原来的内容都没消除,此方法就是消除上一条新增后框框中的信息===*/
function reset_form(ele) {
//重置内容
$(ele)[0].reset();
//清空样式,找到该元素下的所有内容里包含这两个class的内容,清掉它们
$(ele).find("*").removeClass("has-error has-success");
//找到所有class为helt-block(提示框所在的一小块区域),清空内容
$(ele).find(".help-block").text("");
}
/*=============点击新增按钮弹出悬浮框,(在“新增”键处)============*/
$("#emp_add_modal_btn").click(function() {
//重置表单
reset_form("#empAddModal form");
//发送ajax请求,查出部门信息,显示在下拉列表中
getDepats("#dept_add_select");
//弹出框框
$("#empAddModal").modal({
//令悬浮框不会删除
backdrop : "static"
});
});
/*==============封装方法:查出总共有几个部门,然后添加到下拉表中======================*/
function getDepats(ele) {
//每次请求前 先清空数据
$(ele).empty();
$.ajax({
url : "${APP_PATH}/depts",
type : "GET",
success : function(result) {
//显示部门信息在下拉列表中
$.each(result.extend.depts, function() {
var optionEle = $("<option></option>").append(
this.deptName).attr("value", this.deptId);
optionEle.appendTo(ele);
});
}
});
}
/* ===========前端检验数据是否合理,但是这样不保险,在下面还有后台检验====================*/
function validate_add_form() {
//1、拿到要校验的数据,使用正则表达式进行校验
var empName = $("#empName_add_input").val();
//bootstrap的内容,在input的父元素上添加如下class
var regName = /(^[a-zA-Z0-9_-]{4,16}$)|(^[\u2E80-\u9FFF]{2,5})/;
if (!regName.test(empName)) {
show_validate_msg("#empName_add_input", "error",
"用户名格式错误(前端校验)");
return false;
} else {
show_validate_msg("#empName_add_input", "success", "");
}
//校验邮箱
var email = $("#email_add_input").val();
var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
if (!regEmail.test(email)) {
//bootstrap的内容,在input的父元素上添加如下class
show_validate_msg("#email_add_input", "error", "邮件格式错误(前端校验)");
return false;
} else {
show_validate_msg("#email_add_input", "success", "");
}
return true;
}
/*=======================封装检验重复的方法,便于多处引用===============================*/
function show_validate_msg(ele, status, msg) {
//应该清空这个元素之前的样式
$(ele).parent().removeClass("has-success has-error");
$(ele).next("span").text("");
if ("success" == status) {
$(ele).parent().addClass("has-success");
$(ele).next("span").text("");
} else if ("error" == status) {
$(ele).parent().addClass("has-error");
$(ele).next("span").text(msg);
}
}
/*===========================检验员工是否重复,并进行提示========================*/
$("#empName_add_input").change(
function() {
var empName = this.value;
//发送ajax请求是否可用
$.ajax({
url : "${APP_PATH}/checkuser",
data : "empName=" + empName,
type : "POST",
success : function(result) {
//此处code是Msg.java中的属性
if (result.code == 100) {
show_validate_msg("#empName_add_input",
"success", "用户名可用");
//如果成功,给保存按钮的键添加个自定义的属性,用于判断能不能点下保存
$("#emp_save_btn").attr("ajax-va", "success");
} else {
//传出的错误信息,是在EmployeeController中自定义的va_msg
show_validate_msg("#empName_add_input",
"error", result.extend.va_msg);
$("#emp_save_btn").attr("ajax-va", "error");
}
}
});
});
/*======================点击按钮后,就会保存数据,并且实现在这实现后台检验=====================*/
$("#emp_save_btn")
.click(
function() {
//对提交的数据进行校验
if (!validate_add_form()) {
return false;
}
//1、判断之前的ajax用户名是否成功,如果成功,才发送ajax
if ($(this).attr("ajax-va") == "error") {
return false;
}
//2、ajax保存员工
$
.ajax({
url : "${APP_PATH}/emp",
type : "POST",
data : $("#empAddModal form")
.serialize(),
success : function(result) {
//员工保存成功后,判断返回后台返回的结果状态码(JSR303)
if (result.code == 100) {
//1、关闭模态框;就用bootstrap的方法
$("#empAddModal").modal('hide');
//2、来到最后一页,显示保存的数据
//发送ajax请求显示最后一页数据即可
//此处利用pagehelper中,如果跳转的页面数大,则自动访问最后一页
to_page(totalRecord);
} else {
//有哪个字段的错误信息就显示哪个字段的,undefined是没有错误下会自动带上的信息
if (undefined != result.extend.errorFields.email) {
//显示邮箱错误信息
show_validate_msg(
"#email_add_input",
"error",
result.extend.errorFields.email);
}
if (undefined != result.extend.errorFields.empName) {
//显示员工错误信息
show_validate_msg(
"#empName_add_input",
"error",
result.extend.errorFields.empName);
}
}
}
});
});
/* ============================以下是修改员工内容======================================== */
/*=====================查询员工信息(和查询部门信息一样)========================*/
function getEmp(id) {
$.ajax({
url : "${APP_PATH}/emp/" + id,
type : "GET",
success : function(result) {
var empData = result.extend.emp;
//获取姓名和邮箱信息,因为姓名和邮箱格式不一样,因此实现方式一个text,一个val
$("#empName_update_static").text(empData.empName);
$("#email_update_input").val(empData.email);
//单选框和下拉列表的选中方式可以搜搜jQuery文档的val方法
$("#empUpdateModal input[name=gender]").val(
[ empData.gender ]);
$("#empUpdateModal select").val([ empData.dId ]);
}
});
}
/*========================点击“编辑”后,弹出悬浮框===========================*/
/* 下面这种绑定方法是不行的,因为编辑等内容,都是在<script>中用ajax发送请求得到的。
但是js先执行,因此可以说,我们这里是先绑定,后出现那些按钮。因此不行
解决方法:1、创建按钮时候绑定事件(太耦合)。2、使用jquery提供的on方法(自行搜索on的用法)
$(".edit_btn").click(function() {
alert("2334");
});
*/
$(document).on("click", ".edit_btn", function() {
//1、查出员工信息,并显示员工信息,此处用到了bootstrap的静态控件
//2、同时我们创建按钮时候添加了个属性edit-id获取当前按钮的id(和员工id一样),从而获取员工id
getEmp($(this).attr("edit-id"));
//2、查出部门信息,并显示部门列表
getDepats("#empUpdateModal select");
//3、把员工id传递给模态框的更新按钮。给更新按钮添加edit-id属性,并传递id值
$("#emp_update_btn").attr("edit-id", $(this).attr("edit-id"));
//4、弹出模态框,并显示查询到的信息
$("#empUpdateModal").modal({
//令悬浮框不会删除
backdrop : "static"
});
});
/*=======================点击“更新”后,更新员工===========================*/
$("#emp_update_btn")
.click(
function() {
//1、验证邮箱是否合法,这是上面前端校验的内容,由于没封装方法,就直接复制拿来用了
var email = $("#email_update_input").val();
var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
if (!regEmail.test(email)) {
show_validate_msg("#email_update_input",
"error", "邮件格式错误(前端校验)");
return false;
} else {
show_validate_msg("#email_update_input",
"success", "");
}
//2、发送ajax请求,保存员工数据,根据我们之前的规定,用put方式来更新
$.ajax({
//在前面的方法中,我们给更新按钮加上了edit-id属性
url : "${APP_PATH}/emp/"
+ $(this).attr("edit-id"),
type : "PUT",
data : $("#empUpdateModal form").serialize(),
success : function(result) {
//1、关闭对话框,
$("#empUpdateModal").modal("hide");
//2、回到本页面
to_page(currentPage);
}
});
});
/*==========================单个删除按钮========================*/
$(document).on("click", ".delete_btn", function() {
//1、弹出确认是否删除对话框,找到列表中的第三个td(即姓名)
var empName = $(this).parents("tr").find("td:eq(2)").text();
var empId = $(this).attr("del-id");
//制定弹出框的内容
if (confirm("确认删除[" + empName + "]吗?")) {
//确认,发送ajax请求进行删除
$.ajax({
url : "${APP_PATH}/emp/" + empId,
type : "DELETE",
success : function(result) {
to_page(currentPage);
}
});
}
});
/*==============点击最上面的全选/全不选,则该页所有内容都会勾选=====================*/
$("#check_all").click(function() {
/*attr获取checked是undefined,用prop修改和读取dom原生属性的值
此处是判断当前元素是否被选中$(this).prop("checked")
且该方法第二个参数应该是传入当前状态? 这样就完成了全选全不选的效果
*/
$(this).prop("checked");
$(".check_item").prop("checked", $(this).prop("checked"));
});
/*=========================当下面的五个小选择框选满时候,上面的全选也会勾选============================*/
$(document)
.on(
"click",
".check_item",
function() {
//判断当前选中的元素是不是五个,是的话,则上面的全选也会勾上
//:checked是jquery的内容,用来封装已经勾选的内容
var flag = $(".check_item:checked").length == $(".check_item").length
$("#check_all").prop("checked", flag);
});
/*==================批量删除====================*/
$("#emp_delete_all_btn").click(
function() {
var empNames = "";
var del_idstr = "";
$.each($(".check_item:checked"), function() {
//组装员工名字的字符串
empNames += $(this).parents("tr").find("td:eq(2)")
.text()
+ ",";
//组装员工id,变成字符串来传入
del_idstr += $(this).parents("tr").find("td:eq(1)")
.text()
+ "-";
});
//去除empNames的逗号
empNames = empNames.substring(0, empNames.length - 1);
//去除del_idstr多出来的横杠
del_idstr = del_idstr.substring(0, del_idstr.length - 1);
if (confirm("确认删除【" + empNames + "】吗?")) {
//发送ajax
$.ajax({
url : "${APP_PATH}/emp/" + del_idstr,
type : "DELETE",
success : function(result) {
alert(result.msg);
//回到当前页面
to_page(currentPage);
}
});
}
});
</script>
</body>
</html>