JQuery使用Datatable插件(三)——使用ajax实现增删改查以及自定义按钮的实现

看这个文章有不懂可以看一下我前面写的两篇文章

1.https://blog.csdn.net/ChOLg/article/details/95326534(简单使用,使用假数据本地分页)

2.https://blog.csdn.net/ChOLg/article/details/95334063(用ajax与后端交互)

 

一、html代码(使用了bootstrap的模态框进行增删改出的操作)




管理员管理













ID 用户名 用户头像 联系电话 邮箱 创建时间 状态 操作

二、实现datatable的myDatatable.js代码

注意:1.datatable使用自定义button时需要引入dataTables.buttons.min.js和buttons.dataTables.min.css两个文件

2.由于datatable的editor需要收费,所以可以使用bootstrap模态框实现相同功能

$(function() {
/**
 * DataTable属性配置以及生成datatable
 */	
    $('#myDatatable').DataTable({
    	"select": true,
        "processing": true,//数据加载时显示进度条
        "searching": false,//启用搜索功能
        "serverSide": true,//启用服务端分页(这是使用Ajax服务端的必须配置)
        "ajax": {
	        "url": "/booking/admin/showPage",
	        "type": "POST",
	        "data": function (d) {
	            d.pageNo = $("#myDatatable").DataTable().page();//获取当前页码
	            var key = $("#search").val();//获取搜索框关键字
	            d.extraSerach=key;//查询条件
	        }
	    },
	    "dom": 'l<"right"B>rtip',//自定义文档对象,因为使用了自定义button,B代表Button,right是绑定在button上从classs,已经在showPage.jsp页面定义
	    //自定义button,实现添加用户、批量删除等操作,其中添加用户使用bootstrap的模态框实现(模态框在showPage.jsp页面配置,使用模态框时最好将其隐藏起来,可以解决引入模态框时影响页面其他布局焦点消失的问题)
	    "buttons": [
            {
                text: '添加用户',
                action: function ( e, dt, node, config ) {
                	$("#addWindow").modal();//启用模态框,关闭调用$("#addWindow").modal(false)
                }
            },
            {
                text: '批量删除',
                action: function ( e, dt, node, config ) {
                	var strIds=[];
                	$("input:checked").each(function(){
                		if($(this).attr("name")!="checkAll"){
                			strIds.push($(this).parents("tr").children().eq(1).html());//获取选中的用户                 			
                		}
                	});
                	var strIds = strIds.join(",");//将选中的用户拼成?,?,?的格式
                	var ids = {"ids":strIds};
                	if(strIds!=null&&strIds.trim()!=""){
                		var option = confirm("是否确认删除?删除后无法恢复!");
                		if(option){
                			$.ajax({
                				url :"/booking/admin/deleteByIds",
                				type: "POST",
                				traditional: true,
                				contentType: "application/json",
                				data:JSON.stringify(ids),
                				success: function(data){
                					var table = $('#myDatatable').DataTable();
                					table.draw(false);
                				}
                			});
                		}
                	}else{
                		alert("请选择要删除的用户!");
                	}
                }
            }
        ],
        "columns": [
        	/**
        	 * 设置列,必须跟后端传来的数据名保持一致(null代表没有对应数据),需要特别操作时给数据绑定函数,
        	 * "render":function (data, type, full, meta),其中的data就是对应列从后台传来的数据,直接使用即可
        	 */
        	{"data":"null","render":function (data, type, full, meta) {
	            return " ";
	        }},
            {"data": "uid"},
            {"data": "uname"},
            {"data": "uicon","render":function (data, type, full, meta){
            	if(data){
            		var content="";
            	}else{
            		var content="";
            	}
	            return content;
            }},
            {"data": "telephone"},
            {"data": "email"},
            {"data": "create_time"},
            {"data": "enable","render":function (data, type, full, meta) {
            	var content="";
            	if(data){
            		content+="有效";
            	}else{
            		content+="无效";
            	}
	            return content;
	        }},
            {"data": "enable","render":function (data, type, full, meta) {
            	var content=" 
"; if(data){ content+=""; }else{ content+=""; } content+=""; content+=""; content+="
"; return content; }}, ], "info":true, //分页信息提示等等 "paging": true, "pagingType": "full_numbers", "bLengthChange": true, //开关,是否显示每页显示多少条数据的下拉框 "aLengthMenu": [[5, 10, 20], [5, 10, 20]],//设置每页显示数据条数的下拉选项 'iDisplayLength': 10, //每页初始显示5条记录 'bFilter': false, //是否使用内置的过滤功能(是否去掉搜索框) "bSort": false, //是否可排序 //"aoColumnDefs": [ { "bSortable": false, "aTargets": [ 0 ] }],//进制某列排序 // "aaSorting": [[1, "asc"]],//指定某列按照什么规则排序 "oLanguage":{ //语言转换 "sProcessing": "处理中...", "sLengthMenu": "显示 _MENU_ 项结果", "sZeroRecords": "没有匹配结果", "sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项", "sInfoEmpty": "显示第 0 至 0 项结果,共 0 项", "sInfoFiltered": "(由 _MAX_ 项结果过滤)", "sInfoPostFix": "", "sSearch": "搜索:", "sUrl": "", "sEmptyTable": "表中数据为空", "sLoadingRecords": "载入中...", "sInfoThousands": ",", "oPaginate": { "sFirst": " 首页 ", "sPrevious": " 上一页 ", "sNext": " 下一页 ", "sLast": " 末页 " }, "oAria": { "sSortAscending": ": 以升序排列此列", "sSortDescending": ": 以降序排列此列" } } }); /** * 全选和全不选 */ $('#checkAll').change(function () { var checked = $(this).prop("checked"); $("input[name='checkbox']").each(function() { $(this).prop("checked", checked); }); }); /** * 获取搜索框关键字并将其写进datatable中的key中 */ $("#searchBtn").click(function(){ var key = $("#search").val(); var table = $('#myDatatable').DataTable(); table.search(key).draw();//将查询关键字写进datatable的key中 }); /** * 编辑用户时实现点击图片上传图片,同时能先预览 */ $("#uicon").click(function(){ $("#upload").click(); $("#upload").change(function(){ var url = getImageUrl(this.files[0]); if(url){ $("#uicon").attr("src",url); } }) }); /** * 添加用户时实现点击图片上传图片,同时能先预览 */ $("#newUicon").click(function(){ $("#newUpload").click(); $("#newUpload").change(function(){ var url = getImageUrl(this.files[0]); if(url){ $("#newUicon").attr("src",url); } }) }); /** * 添加用户后与后台进行交互 */ $("#addUser").click(function(){ var uname = $("#newUname").val(); var file = $("#newUpload")[0].files[0]; var telephone = $("#newTelephone").val(); var email = $("#newEmail").val(); var data = new FormData();//通过formdata封装数据 data.append("uname",uname); data.append("telephone",telephone); data.append("email",email); //判断是否有文件上传 if(file){ data.append("isMultipart",true); }else{ data.append("isMultipart",false); } data.append("file",file); $.ajax({ url: "/booking/user/register", type: "POST", data: data, dataType: "json", processData: false,//使用formdata传递数据时必须设置processData: false contentType: false,//使用formdata传递数据时必须设置contentType: false success: function(data) { if(data.result=="success"){ alert("添加用户成功!"); $('#editorWindow').modal('hide'); }else{ alert("添加用户失败!"); } var table = $('#myDatatable').DataTable(); table.draw(false); } }); }); /** * 编辑用户后与后台进行交互 */ $("#update").click(function(){ var uid = $("#uid").val(); var uname = $("#uname").val(); var file = $("#upload")[0].files[0]; var telephone = $("#telephone").val(); var email = $("#email").val(); var data = new FormData();//通过formdata封装数据 data.append("uid",uid); data.append("uname",uname); data.append("telephone",telephone); data.append("email",email); //判断是否有文件上传 if(file){ data.append("isMultipart",true); }else{ data.append("isMultipart",false); } data.append("file",file); $.ajax({ url: "/booking/admin/update", type: "POST", data: data, dataType: "json", processData: false,//使用formdata传递数据时必须设置processData: false contentType: false,//使用formdata传递数据时必须设置contentType: false success: function(data) { if(data.result=="success"){ console.log("成功"); $('#editorWindow').modal('hide'); }else{ console.log("失败"); } var table = $('#myDatatable').DataTable(); table.draw(false); } }); }); }); /** * 不同浏览器获取上传文件url,此处不是文件的真正上传url,只是为了实现上传文件在线预览 * @param file * @returns */ function getImageUrl(file){ var url = null ; if (window.createObjectURL!=undefined) { // basic url = window.createObjectURL(file) ; } else if (window.URL!=undefined) { // mozilla(firefox) url = window.URL.createObjectURL(file) ; } else if (window.webkitURL!=undefined) { // webkit or chrome url = window.webkitURL.createObjectURL(file) ; } return url ; } /** * 修改用户状态 * @param obj * @returns */ function fnChangeAble(obj){ var enable = $(obj).find(".fa").html(); var newEnable = false; if(enable=="启用"){ newEnable = true; }else{ newEnable = false; } var id = $(obj).parents("tr").children().eq(1).html(); var data = {"uid":id,"newEnable":newEnable}; $.ajax({ url :"/booking/admin/changeEnable", type: "POST", contentType: "application/json", data: JSON.stringify(data), dataType: "json", success: function(data){ if(data.result=="success"){ console.log("成功"); }else{ console.log("失败"); } var table = $('#myDatatable').DataTable(); table.draw(false);//刷新当前页面 } }); } /** * 编辑用户信息时显示当前用户信息 * @param obj * @returns */ function fnEdit(obj){ var row = $(obj).parents("tr")[0]; var rowData = $("#myDatatable").dataTable().fnGetData(row);//获取datatable指定行的所有数据 $("#editorWindow").modal();//初始化模态框 $("#uid").val(rowData.uid); $("#uname").val(rowData.uname); if(rowData.uicon!=null){ $("#uicon").attr("src","/booking/views/admin/images/userIcon/"+rowData.uicon); }else{ $("#uicon").attr("src","#"); } $("#telephone").val(rowData.telephone); $("#email").val(rowData.email); $("#create_time").val(rowData.create_time); if(rowData.enable){ $("#enable").val("有效"); }else{ $("#enable").val("无效"); } } /** * 删除单个用户 * @param obj * @returns */ function fnDelete(obj){ var option = confirm("是否确认删除?删除后无法恢复!"); if(option){ var id = $(obj).parents("tr").children().eq(1).html(); var data = {"uid":id}; $.ajax({ url :"/booking/admin/delete", type: "POST", contentType: "application/json", data: JSON.stringify(data), success: function(data){ var table = $('#myDatatable').DataTable(); table.draw(false);//刷新当前页面 } }); } }

三、后台java代码,使用springmvc

1.UserDao.java

建议:不了解JPA的可以看看这个链接:https://blog.csdn.net/jtracydy/article/details/79514281

/**
 * 继承JPA,实现系统函数实现CRUD操作
 * 继承PagingAndSortingRepository、JpaSpecificationExecutor两个接口
 * @author 张小旭
 *
 */
@Repository
public interface UserDao extends PagingAndSortingRepository,JpaSpecificationExecutor{
	//doSomething
}

2.UserService.java(接口) 

public interface UserService {
//	CrudRepository接口:
	public void save(User entity);
	public void saveAll(List entities);
	public User findById(Long id);
	public boolean existsById(Long id);
	public List findAll();
	public List findAllById(List ids);
	public long count();
	public void deleteById(Long id);
	public void delete(User entity);
	public void deleteAll(List entities);
	public void deleteAll(Long[] ids);
//	PagingAndSortingRepository extends CrudRepository接口:
	public List findAll(Sort sort);
	public Page findAll(Pageable pageable);
	public Page findAll(Specification spec, Pageable pageable);

}

3.实现UserService接口UserServiceImpl.java

@Service
@Transactional(readOnly=true)
public class UserServiceImpl implements UserService{
	@Autowired
	private UserDao userDao;
	@Autowired
	private UserDTO userDTO;

	@Override
	public void save(User entity) {
		userDao.save(entity);
	}

	@Override
	public void saveAll(List entities) {
		userDao.saveAll(entities);
	}

	@Override
	public User findById(Long id) {
		User user = userDao.findById(id).get();
		return user;
	}
	
	@Override
	public boolean existsById(Long id) {
		return userDao.existsById(id);
	}
	
	@Override
	public List findAll() {
		return (List) userDao.findAll();
	}

	@Override
	public List findAllById(List ids) {
		return (List) userDao.findAllById(ids);
	}

	@Override
	public long count() {
		return userDao.count();
	}

	@Override
	public void deleteById(Long id) {
		userDao.deleteById(id);
	}

	@Override
	public void delete(User entity) {
		userDao.delete(entity);
	}

	@Override
	public void deleteAll(List entities) {
		userDao.deleteAll(entities);
	}

	@Override
	public void deleteAll(Long[] ids) {
		ArrayList idList = new ArrayList(Arrays.asList(ids));
		List users = (List) userDao.findAllById(idList);
		if(users!=null) {
			userDao.deleteAll(users);
		}
	}

	@Override
	public List findAll(Sort sort) {
		return (List) userDao.findAll(sort);
	}

	@Override
	public Page findAll(Pageable pageable) {
		return userDao.findAll(pageable);
	}

	@Override
	public Page findAll(Specification spec, Pageable pageable) {
		return userDao.findAll(spec, pageable);
	}
}

 2.UserController.java(controller层)

@Controller
@RequestMapping(value="/admin")
public class AdminController {
	@Autowired
	private UserService userService;
	
	/**
	 * 实现修改用户数据
	 * @param request 客户端请求对象
	 * @param multipartRequest 文件上传请求对象,客户端上传文件时enctype属性的必须属性值设为multipart/form-data;不过由于客户端使用bootstrap框架,好像默认就是了
	 * @return
	 */
	@PostMapping(value="update")
	public @ResponseBody String updateUser(HttpServletRequest request, MultipartHttpServletRequest multipartRequest) {
		String uname = request.getParameter("uname");
		String telephone = request.getParameter("telephone");
		String email = request.getParameter("email");
		Long uid = Long.parseLong(request.getParameter("uid"));
		User user = userService.findById(uid);
		String uicon = null;
		//判断是否有文件上传(根据客户端判断后的结果)
		if (Boolean.parseBoolean(request.getParameter("isMultipart"))) {
            MultipartFile file = multipartRequest.getFile("file");//获取上传文件
            String path = request.getSession().getServletContext().getRealPath("/views/admin/images/userIcon/");//文件存放路径
    		uicon = UploadFile.uploadImage(file,path);//保存文件
    		//判断当前是否有头像,旧头像是否存在本地,是就删除本地图片
    		if(user.getUicon()!=null) {
    			String realPath = "/views/admin/images/userIcon/"+user.getUicon();
        		String uiconPath = request.getSession().getServletContext().getRealPath(realPath);//图片存放路径
        		File uiconFile = new File(uiconPath);
        		if(uiconFile.exists()) {
        			uiconFile.delete();//删除旧头像图片
        		}
    		}
		}
		if(user!=null) {
			user.setUname(uname);
			user.setTelephone(telephone);
			user.setEmail(email);
			if(uicon!=null) {
				user.setUicon(uicon);
			}
			userService.save(user);
			return "{\"result\":\"success\"}";
		}else {
			return "{\"result\":\"fail\"}";
		}
	}
	/**
	 * 实现批量删除用户
	 * @param map 接受前台json数据
	 */
	@PostMapping(value="deleteByIds")
	public @ResponseBody void deleteByUids(@RequestBody Map map) {
		String[] strIds = map.get("ids").split(",");//将数据ids转换成string数组
		Long[] ids = new Long[strIds.length];
		//将ids的string数组转换成Long数组,方便直接调用系统函数
		for(int i=0;i map) {
		Long uid = null;
		if(map.containsKey("uid")){
	        uid = Long.parseLong(map.get("uid"));
	    }
		userService.deleteById(uid);
	}
	
	/**
	 * 实现用户状态的修改
	 * @param map 接收前台json数据
	 * @return
	 */
	@PostMapping(value="changeEnable")
	public @ResponseBody String changeEnable(@RequestBody Map map) {
		Long uid = null;
		Boolean newEnable = null;
		if(map.containsKey("uid")){
	        uid = Long.parseLong(map.get("uid"));
	    }
	    if(map.containsKey("newEnable")){
	        newEnable =Boolean.parseBoolean(map.get("newEnable"));
	    }
		User user = userService.findById(uid);
		if(user!=null) {
			user.setEnable(newEnable);
			userService.save(user);
			return "{\"result\":\"success\"}";
		}else {
			return "{\"result\":\"fail\"}";
		}
		
	}
	/**
	 * 实现管理员分页、查询管理
	 * @param pageNo 当前页
	 * @param length 每页的长度
	 * @param draw 没有特别作用,前台传来什么就返回什么,没有则返回1
	 * @param extraSerach 查询条件,实现模糊查询
	 * @return
	 */
	@PostMapping(value="showPage")
	public @ResponseBody String showPage(@RequestParam Integer pageNo,Integer length,Integer draw,String extraSerach) {
		UserDTO queryDto = new UserDTO();
		queryDto.setKey(extraSerach);//查询条件
		PageRequest pageable = PageRequest.of(pageNo, length, Direction.ASC, "uid");//分页条件
		Page userPage = userService.findAll(UserDTO.getSpecification(queryDto), pageable);
		HashMap result = new HashMap<>();
		List data = new ArrayList();
		result.put("data", data);//用户数据
		result.put("draw", draw);//前端传来什么就返回什么,如果没有就返回1
		result.put("recordsTotal", userPage.getTotalElements());//总记录数
		result.put("recordsFiltered", userPage.getTotalElements());//查询过滤后的总记录数,跟recordsTotal保持一致,前台会根据数据自动进行显示
		ObjectMapper jsonObject = new ObjectMapper();
		String json = null;
		try {
			json = jsonObject.writeValueAsString(result);//将所有数据转化成json字符串
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return json;
	}
}

五、最后上一张效果图

 

你可能感兴趣的:(小记,datatable,modal,button,jquery,spring)