1.环境搭建
引入ajaxfileupload.js文件(ajaxfileupload.js是基于jQuery编写的插件,故此也需要引入jQuery文件)
<script type="text/javascript" src="${pageContext.request.contextPath}/statics/jqgrid/js/ajaxfileupload.js"></script>
引入jqgrid相关文件
<!--引入样式文件-->
<link rel="stylesheet" href="${pageContext.request.contextPath}/statics/boot/css/bootstrap.css" type="text/css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/statics/jqgrid/css/trirand/ui.jqgrid-bootstrap.css" type="text/css">
<!--引入js功能文件-->
<script src="${pageContext.request.contextPath}/statics/boot/js/jquery-2.2.1.min.js" type="text/javascript"></script>
<script src="${pageContext.request.contextPath}/statics/boot/js/bootstrap.min.js" type="text/javascript"></script>
<script src="${pageContext.request.contextPath}/statics/jqgrid/js/trirand/i18n/grid.locale-cn.js" type="text/javascript"></script>
<script src="${pageContext.request.contextPath}/statics/jqgrid/js/trirand/jquery.jqGrid.min.js" type="text/javascript"></script>
2.页面代码编写
下例为上传封面cover
<table id="banner-table"></table>
<div id="banner-pager"></div>
<script>
$(function () {
//展示供应商信息
$("#banner-table").jqGrid({
// 整合使用bootstrap样式的属性
styleUI:'Bootstrap',
url:'${pageContext.request.contextPath}/banner/findBannerByPage',
editurl:'${pageContext.request.contextPath}/banner/operBanner',
caption : "轮播图详细信息", //设置表格名
datatype:'json',
colNames:['名称','封面','描述','创建日期','状态','最后修改时间'],
// 开启表格编辑模式
cellEdit:true,
colModel:[
// {name:'id',align:'center'},
{name:'title',align:'center',editable:true},
{
name:'cover',
formatter:function(value,options,row){
return '<img src="${pageContext.request.contextPath}/view/banner/image/'+row.cover+'" width="150px" height="60px"/>';
},
// index:'cover', 相当于索引id,唯一标识(没有用到)
align:'center',
editable:true,
//editoptions: {enctype: "multipart/form-data"},
//代表编辑后表单有文件类型数据传输,(没有用到)
edittype:'file', //设置后,编辑时此选项为文件类型
},
{name:'description',align:'center',editable:true},
{
name:'createDate',
align:'center',
//日期格式化
formatter:"date",
formatoptions: {srcformat:'Y-m-d H:i:s',newformat:'Y-m-d'}
},
{name:'status',align:'center',editable:true},
{
name:'lastUpdateDate',
align:'center',
//日期格式化
formatter:"date",
formatoptions: {srcformat:'Y-m-d H:i:s',newformat:'Y-m-d'}
},
],
//数据表格是否自适应父容器的大小宽度
autowidth:true,
//显示行号
rownumbers:true,
//在第一列前加入复选框
multiselect:true,
//设置高度
height:400,
//添加分页
//使用分页工具栏
pager:'#banner-pager',
rowList:[5,10,15],
rowNum:10,
page:1,
//显示总记录数
viewrecords:true,
}).navGrid('#banner-pager',{edit : true,add : true,del : true,search:false},
//.navGrid("工具栏id",{显示内容},{修改操作},{添加操作}),{删除操作}
//注意注意!!!!!!!!!!!顺序一定不能错
//=====控制修改操作====================================
{
//修改后关闭编辑框
closeAfterEdit:true,
},
//=====控制添加操作======================================
{
//添加后关闭编辑框
closeAfterAdd: true,
//提交后:
//执行完添加操作后这里返回了一个Map<String,Object>
//里面存有刚添加数据的ID和状态码 {data:id;code:200/404/500...}
afterSubmit:function (response) {
var id = response.responseJSON.data; //返回的id
var code = response.responseJSON.code; //返回的状态码
if(code==200) {
$.ajaxFileUpload({
fileElementId: "cover", //需要上传的文件域的ID,即<input type="file">的ID。
url: "${pageContext.request.contextPath}/banner/upload", //后台方法的路径
type: 'post', //当要提交自定义参数时,这个参数要设置成post
data: {id: id}, //发送请求时传递的参数(数据)
//dataType: 'json', //服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。不要加它了,太恶心了!!
// secureuri: false, //是否启用安全提交,默认为false。
// async : true, //是否是异步
success:function() {
alert("成功!");
$("#banner-table").trigger("reloadGrid");
}
})
return "true";
//注意注意!!!!!!!这个一定不能少,随便返回一个字符串即可
//ajaxFileUpload需要一个返回值,否则上述设置的修改后关闭编辑框不会生效
}
}
}
);
})
</script>
3.后台代码编写
@RequestMapping("banner")
@RestController
public class BannerController extends BaseApiService{
@Autowired
private BannerService bannerService;
@RequestMapping("findBannerByPage")
/**
* page:查询页数
* rows:每页显示条数
* searchField: 查询条件
* searchString: 查询内容
* 加入分页工具栏后,远程响应json数据格式为:
* {"rows":[当前页结果(list)],"page":"当前页","total":"总页数","records":"总条数"}
*/
public Map<String,Object> findBannerByPage(Integer page, Integer rows,
String searchField, String searchString){
//创建结果集
List<Banner> bannerList = null;
Integer records = 0;
HashMap<String, Object> map = new HashMap<>();
Integer total = 0;
//判断是否为模糊查询
if(searchField==null){
//查询集合
bannerList = bannerService.findAllByPage(page, rows);
//查询总条数
records = bannerService.getCount();
//计算总页数
total = records%rows==0?records/rows:records/rows+1;
}else {
//查询集合
bannerList = bannerService.findAllByPageBySearch(page, rows,searchField,searchString);
//查询总条数
records = bannerService.getCountBySearch(searchField,searchString);
//计算总页数
total = records%rows==0?records/rows:records/rows+1;
}
//封装的一个map集合
return setPageMap(bannerList,page,total,records);
}
@RequestMapping("operBanner")
public Map<String,Object> operBanner(Banner banner,MultipartFile cover,String id,String oper) {
//添加
if("add".equals(oper)){
String i = bannerService.add(banner);
return setResultSuccessData(i);
}
//修改
if("edit".equals(oper)){
String i = bannerService.update(banner);
return setResultSuccessData(i);
}
//删除
if("del".equals(oper)){
String[] ids = id.split(",");
for (String i : ids) {
bannerService.delete(i);
}
}
return null;
}
@RequestMapping("upload")
public void upload(MultipartFile cover, String id, HttpSession session) throws IOException {
System.out.println("id===="+id);
System.out.println("cover===="+cover.getOriginalFilename());
if ("".equals(cover.getOriginalFilename())) throw new RuntimeException("文件为空");
//获取文件上传路径
String realPath = session.getServletContext().getRealPath("/view/banner/image");
//文件上传
cover.transferTo(new File(realPath,cover.getOriginalFilename()));
//修改数据库图片中的路径
Banner banner = new Banner();
banner.setId(id).setCover(cover.getOriginalFilename());
bannerService.update(banner);
//return "success";
}
}
4.流程介绍
如上例,主要实现使用jqgrid添加一条数据时,该数据为图片类型,展示时要求展示图片。
方案:
a).先将普通字段数据入库,添加完成后返回一个Map<String,Object>类型集合,存入数据data=刚添加数据的id,(code=200/500/404…状态码)。
b).前台在控制添加数据(后面介绍)后加入事件,afterSubmit代表调教数据之后触发。然后使用ajaxFileUpload发送ajax请求上传文件。
afterSubmit:function (response) {
var id = response.responseJSON.data; //返回的id
var code = response.responseJSON.code; //返回的状态码
...
}
$.ajaxFileUpload({
fileElementId: "cover", //需要上传的文件域的ID,即<input type="file">的ID。
url: "${pageContext.request.contextPath}/banner/upload", //后台方法的路径
type: 'post', //当要提交自定义参数时,这个参数要设置成post
data: {id: id}, //发送请求时传递的参数(数据)
dataType: 'json', //服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。
// secureuri: false, //是否启用安全提交,默认为false。
// async : true, //是否是异步
success:function() {
//alert("成功!");
$("#banner-table").trigger("reloadGrid");
}
})
c).在控制上传文件的controller里进行文件上传然后修改数据库中该条数据的图片路径。
if ("".equals(cover.getOriginalFilename())) throw new RuntimeException("文件为空");
//获取文件上传路径
String realPath = session.getServletContext().getRealPath("/view/banner/image");
//文件上传
cover.transferTo(new File(realPath,cover.getOriginalFilename()));
//修改数据库图片中的路径
Banner banner = new Banner();
banner.setId(id).setCover(cover.getOriginalFilename());
bannerService.update(banner);
return "success";
注意事项:
- 如果文件框内没有文件上传该字段为“”,而并非nul。
- 在修改时如果修改图片则正常,但如果没有修改图片则会把数据库中原图片路径置空
原因:没有文件上传该字段为“”,会直接传入实体类中以至于修改数据库。
解决方法:如果使用通用mapper,则在service中更新数据之前判断是否为空串,如果是则置为null;如果没有使用通用mapper,则获取原始数据重新赋值即可。
if ("".equals(banner.getCover())) banner.setCover(null);
5.注意事项
a). jqgrid中对工具栏id、工具栏展示功能设置、修改、添加、删除操作的顺序有严格要求,不可缺少或错位;
.navGrid('#banner-pager',{edit : true,add : true,del : true,search:false},{},{},{})
//.navGrid("工具栏id",{显示内容},{修改操作},{添加操作}),{删除操作}
b). 执行ajaxfileupload请求时,需要有个返回值(任意字符串),否则修改、添加后关闭模态框(closeAfterAdd: true/closeAfterEdit: true)不会生效。
c). 修改或添加操作后刷新表格:此时是执行完文件上传之后,success函数中进行操作。一定注意,如果ajaxfileupload中加入了dataType,请一定要和后台controller中upload方法的返回值类型对应,若不对应则success中方法不会执行,默认请求失败,但不影响文件上传,但需要上传后手动刷新。
综上,还是不要加了!!!!!!!
//服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。
dataType: 'json',
success:function() {
//alert("成功!");
$("#表格id").trigger("reloadGrid");
}