在上一篇文章中,主要介绍了file input插件的初始化和多文件同步上传到服务器的相关配置等。这篇主要介绍file input插件的编辑等。
使用场景:
在后台管理框架中,一条数据中包含不固定的多张图片属性,然后需要同其他数据一起做增删改查。多文件同时新增上一篇已经做过了,需要的请点击打开链接,但是编辑的时候,就需要吧原来上传的图片展示出来,然后可以进行删除和重新上传,,这就是我现在要做的功能。
直接上代码吧。。
1.HTML
2.JS代码 当点击数据的编辑按钮,则通过后台返回的数据初始化编辑页面,并初始化文件上传插件。
很神奇,你会发现,在url中我只配置了deletePic,但是通过调试发现,删除请求的url竟然自动拼接了前面的一段url,我猜测可能是从上面的配置updateUrl而来,或者是从请求头中的Referer而来。
配置的key是请求传递的参数,实测发现名字key不能改成自己的其他名字,而且传递的值不能是对象,这就有个问题了,万一我想传多个值怎么办?那就自己动手丰衣足食,改造源码吧。。
3.更改fileinput.js源码
需求一:将key传递的参数改为: key: "{'id':'1','name':'name1'}"
注意:既然直接传递对象不行,那就传递json字符串吧,然后在源码中转换成json不就行了?
更改源码中2379行左右,当点击删除按钮时,会调用settings,里面就是已经配置好的参数,我们获取key值,然后将单引号替换成双引号,然后转换为json对象,替换data参数。
这里为什么要替换单引号为双引号,为什么不直接在key配置的时候就写双引号呢?别问,我试了,不行,转换会出错,要不就是传递不过来,不然我也不会使用这个多此一举的办法啊。。。你直接传递json字符串到后台,用后台代码解析为json也可以。。然后我们的调试请求发现传递的值就变成我们想要的了。。
好,传值的问题解决了。就可以点击按钮的时候去后台删除此图片了,并传递我们其他的参数。新选择的图片并不会调用后台方法,会直接删除的。
需求二:当用户点击删除按钮的时候,提示他这是原图片,并问他是否确认删除,确认后才去后台调用删除,取消则不删除。这是为了避免用户点错,而导致删除了原图片,那么久需要在后台调用ajax之前执行一段我们的提示代码。
解决:查看API,发现了这么几个事件可以调用。
$('#input-id').on('filepreremove', function(event, id, index) { //只是你删除重新选择的图片才会触发,而删除原图片不会触发。
console.log('id = ' + id + ', index = ' + index);
});
$('#input-id').on('filepredelete', function(event, key, jqXHR, data) { //就是在删除原图片之前触发,而新选择的图片不会触发。能满足我们的要求。
console.log('Key = ' + key);
});
解决一:
采用filepredelete时间监听,在删除之前询问用户是否确定,并在确定后执行后面的。如果采用一般bootstrap的询问框,都是采用回调的方式监听用户操作的,还没等回调结束,后面的代码就已经开始调用ajax执行删除了。所以需要一个js线程的暂停机制,类似于alert,当用户操作后再往下执行,原始的js confirm()方法可以实现询问,然后点击确定则继续执行,所以代码改为:
在源码2323行左右,执行ajax方法中beforSend,我们在filepredelete中返回false,返回false则再return给beforSend,他就会停止执行ajax方法,从而达到我们的目的。
这种方法确实能实现我们的要求,但是使用原始的confirm难免有些难看,也不符合整个系统的UI。但是使用bootstrap其他的询问框,则没办法实现线程暂停机制。但是我们可以在他执行ajax之前去判断,从而阻止执行。
解决二:
更改源码2379行左右,当点击删除按钮时,调用$.ajax(setting)方法之前采用其他bootstrap询问插件来监听,当然你也可以把他封装成一个内部事件,在初始化fileinput的时候去监听,
好了,这就是一些简单的删除原文件的方法,其中不乏需要我们去更改源码来符合我们的需求。后面使用中还遇到什么问题,再来研究吧。
功能相关代码:
场景1:新增图片,并上传之后的删除
filesuccessremove 为对应的名称
此方法内可以写具体删除过程中的相关操作
场景2: 存在默认图片,页面加载完之后的删除
这个删除有是有对应的方法的:
方法1:删除预处理(删除之前想要做什么事)
另外,目前发现一个问题,有预设图片显示在插件中,当选择新图片时,会把之前的预设图片删除掉,这个问题暂时没有具体研究
等有结果或者哪位知情博友有解决方案,欢迎一起分享。
转自 http://www.jb51.net/article/91962.htm
1. 页面部分代码:
1
2
3
4
5
6
7
|
|
说明: 其中onchange()为我业务需要, 上传完成后自动执行一个添加事件。 此方法可以去掉。
2. 获取初始化数据方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// 初始化获取原有文件
$(
function
(){
$.ajax({
type :
"post"
,
url :
"/eim/project/testFileUpload.do"
,
dataType :
"json"
,
success :
function
(data) {
layer.msg(
'操作成功!'
);
showPhotos(data);
},
error:
function
(XMLHttpRequest, textStatus, errorThrown) {
layer.msg(
'操作失败!'
);
}
});
});
|
说明:此处我返回是一个 对象数组:List
3.初始化bootstrap-fileinput 组件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
function
showPhotos(djson){
//后台返回json字符串转换为json对象
var
reData = eval(djson);
// 预览图片json数据组
var
preList =
new
Array();
for
(
var
i = 0; i < reData.length; i++) {
var
array_element = reData[i];
// 此处指针对.txt判断,其余自行添加
if
(array_element.fileIdFile.name.indexOf(
"txt"
)>0){
// 非图片类型的展示
preList[i]=
"
}
else
{
// 图片类型
preList[i]=
"
}
}
var
previewJson = preList;
// 与上面 预览图片json数据组 对应的config数据
var
preConfigList =
new
Array();
for
(
var
i = 0; i < reData.length; i++) {
var
array_element = reData[i];
var
tjson = {caption: array_element.fileIdFile.fileName,
// 展示的文件名
width:
'120px'
,
url:
'/eim/project/deleteFile.do'
,
// 删除url
key: array_element.id,
// 删除是Ajax向后台传递的参数
extra: {id: 100}
};
preConfigList[i] = tjson;
}
// 具体参数自行查询
$(
'#testlogo'
).fileinput({
uploadUrl:
'/eim/upload/uploadFile.do'
,
uploadAsync:
true
,
showCaption:
true
,
showUpload:
true
,
//是否显示上传按钮
showRemove:
false
,
//是否显示删除按钮
showCaption:
true
,
//是否显示输入框
showPreview:
true
,
showCancel:
true
,
dropZoneEnabled:
false
,
maxFileCount: 10,
initialPreviewShowDelete:
true
,
msgFilesTooMany:
"选择上传的文件数量 超过允许的最大数值!"
,
initialPreview: previewJson,
previewFileIcon:
''
,
allowedPreviewTypes: [
'image'
],
previewFileIconSettings: {
'docx'
:
''
,
'xlsx'
:
''
,
'pptx'
:
''
,
'pdf'
:
''
,
'zip'
:
''
,
'sql'
:
''
,
},
initialPreviewConfig: preConfigList
}).off(
'filepreupload'
).on(
'filepreupload'
,
function
() {
// alert(data.url);
}).on(
"fileuploaded"
,
function
(event, outData) {
//文件上传成功后返回的数据, 此处我只保存返回文件的id
var
result = outData.response.id;
// 对应的input 赋值
$(
'#htestlogo'
).val(result).change();
});
}
|
4. 后台java保存文件部分代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@RequestMapping(value=
"/uploadFile"
,method=RequestMethod.POST)
@ResponseBody
public Object uploadFile(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//转型为MultipartHttpServletRequest
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
//获取文件到map容器中
Map
//获取页面传递过来的路径参数
folderPath = request.getParameter(
"folder"
);
String rootPath = BaseConfig.uploadPath;
String filePath = rootPath + folderPath+
"/"
;
//文件上传并返回map容器,map存储了文件信息
FileModel fileModel = UploadifyUtils.uploadFiles(filePath,fileMap);
boolean flag = service.add(fileModel);
if
(flag){
String result = fileModel.getId()+
";"
+fileModel.getFilePath()+
";"
+fileModel.getName()+
";"
+fileModel.getFilePath();
Map map =
new
HashMap<>();
map.put(
"id"
, fileModel.getId());
//返回文件保存ID
//response.getWriter().write(map);
return
map;
}
return
null
;
}
|
说明:该段代码为获取上传文件的部分信息, 如文件名,上传的路径 等,将文件信息保存到表中,对应对象为 FileModel 。
5.上传完成后重新刷新该组件即可。
最终展示效果 :
说明:此处指针对txt文件类型判断, 其余的doc,ppt里面有对应的展示图标,只须在判断是添加对应样式即可
附:根据路径过去/下载文件代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
/**
* 文件下载
*
* @param savePath
* 保存目录
* @param name
* 文件原名
* @param file
* 保存时的名称 包含后缀
* @param request
* @param response
* @return
*/
public static String down(String savePath, String name, String fileName, HttpServletRequest request,
HttpServletResponse response) {
try
{
String path = savePath +
"/"
+ name;
File file =
new
File(path);
if
(!file.exists()) {
// 不存在
request.setAttribute(
"name"
, fileName);
return
"download_error"
;
// 返回下载文件不存在
}
response.setContentType(
"application/octet-stream"
);
// 根据不同浏览器 设置response的Header
String userAgent = request.getHeader(
"User-Agent"
).toLowerCase();
if
(userAgent.indexOf(
"msie"
) != -1) {
// ie浏览器
// System.out.println("ie浏览器");
response.addHeader(
"Content-Disposition"
,
"attachment;filename="
+ URLEncoder.encode(name,
"utf-8"
));
}
else
{
response.addHeader(
"Content-Disposition"
,
"attachment;filename="
+
new
String(name.getBytes(
"utf-8"
),
"ISO8859-1"
));
}
response.addHeader(
"Content-Length"
,
""
+ file.length());
// 以流的形式下载文件
InputStream fis =
new
BufferedInputStream(
new
FileInputStream(path));
byte[] buffer =
new
byte[fis.available()];
fis.read(buffer);
fis.close();
//response.setContentType("image/*"); // 设置返回的文件类型
OutputStream toClient = response.getOutputStream();
OutputStream bos =
new
BufferedOutputStream(toClient);
//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(bos));
bos.write(buffer);
//bw.close();
bos.close();
toClient.close();
return
null
;
}
catch
(Exception e) {
e.printStackTrace();
//response.reset();
return
"exception"
;
// 返回异常页面
} finally {
/*
if
(toClient !=
null
) {
try
{
toClient.close();
}
catch
(IOException e) {
e.printStackTrace();
}
}*/
}
}
|
附:
UploadifyUtils.uploadFiles 部分代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public static FileModel uploadFiles(String savePath,Map
//上传文件
//附件模型对象
FileModel fm=
new
FileModel();
try
{
File file =
new
File(savePath);
//判断文件夹是否存在,如果不存在则创建文件夹
makeDir(file);
if
(fiLeMap!=
null
){
for
(Map.Entry
MultipartFile f = entity.getValue();
if
(f!=
null
&&!f.isEmpty()){
String uuid=UploadifyUtils.getUUID();
//uuid作为保存时的文件名
String ext=UploadifyUtils.getFileExt(f.getOriginalFilename());
//获取文件后缀
//保存文件
File newFile =
new
File(savePath+
"/"
+uuid+
"."
+ext);
f.transferTo(newFile);
fm.setFileName(f.getOriginalFilename());
fm.setName(uuid+
"."
+ext);
fm.setFilePath(savePath);
//保存路径
fm.setExt(ext);
fm.setSize(f.getSize());
}
}
}
return
fm;
}
catch
(Exception e) {
log.error(e);
return
null
;
}
}
|
以上所述是小编给大家介绍的Bootstrap中的fileinput 多图片上传编辑,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
原文链接:http://blog.csdn.net/wuwenjinwuwenjin/article/details/49507595
https://blog.csdn.net/xumoqiu/article/details/53081352?locationNum=1&fps=1
https://ask.csdn.net/questions/354505?sort=id
var preList = new Array();
var listImage = selectItem.FImage.split(",");
var listFUrl = selectItem.FUrl;
var previewJson = preList;
// 与上面 预览图片json数据组 对应的config数据
var initPreviewConfig = new Array();
for ( var i = 1; i < listImage.length; i++) {
var urlList = listImage[i].split(":");
preList[i]= "";
/* alert(urlList[1]);
var config = new Object();
config.caption = urlList[0];
config.url='deleteAssetsImage.html';
config.key=urlList[1];
config.extra = {id: urlList[1]};
initPreviewConfig.push(config);*/
var array_element = urlList[0];
var tjson = {caption: array_element, // 展示的文件名
width: '120px',
url: 'deleteAssetsImage.html', // 删除url
key: 100, // 删除是Ajax向后台传递的参数
extra: function() {
return {id: urlList[1]};
}
};
initPreviewConfig[i] = tjson;
}
initFileInput("projectfile", "uploadZCImage.html",selectItem.FAssetsRegiId);
$("#projectfile").fileinput('refresh', {
initialPreview: preList,
initialPreviewConfig: initPreviewConfig
});
后台 spring
@RequestMapping(value = "/deleteAssetsImage.html", method = RequestMethod.DELETE)
public void deleteAssetsImage(HttpServletRequest request,HttpServletResponse response,ModelMap model) {
response.setCharacterEncoding("UTF-8");
System.out.println("===========================");
try {
//getPara("key");
boolean result = false;
String id = (String) request.getParameter("key");
String id2 = (String) request.getParameter("id");
System.out.println(id2+"==========================="+id);
if(id!=null){
result= assetsService.deleteAssetsImage(Integer.parseInt(id));
}
renderText(response, result);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
始终获取不到参数,用POST请求会报405请求错误,求解答