bootStrap + fileinput多文件上传(使用感悟)

bootStrap+fileinput插件使用:
(坑属实多,可能各种版本之间兼容问题,官方文档给的例

子也是模糊不清的,没有一个完整的Dome,于是在baidu上搜搜搜,也有适用的例子,但也试了很长时间,东拼西凑的才算搞出来了)
一:准备阶段
1、那肯定是要下载fileinput插件了
链接: https://plugins.krajee.com/file-input.

2、要看bootStrap版本和fileinput版本兼容问题,版本不匹配会导致图标和样式出不来

3、插件、js和css样式都引入进来后就开始着手代码部分了。
二:代码部分
新增信息,(也新增图片)
前端引入的js和css文件,(注意顺序,和文档规定的路径,比如:themes,你就必须要创建个themes包)

	<link href="${ctxStatic}/bootstrap/bsie/css/fileinput.css" type="text/css" rel="stylesheet" />

	<script src="${ctxStatic}/bootstrap/bsie/js/fileinput.js" type="text/javascript"></script>
	<script src="${ctxStatic}/bootstrap/bsie/themes/fas/theme.js" type="text/javascript"></script>
	<script src="${ctxStatic}/bootstrap/bsie/themes/explorer-fas/theme.js" type="text/javascript"></script>
	<script src="${ctxStatic}/bootstrap/bsie/js/locales/zh.js" type="text/javascript"></script>

1、(添加)前台初始化代码片

$("#input-100").fileinput({
				<%--uploadUrl: "${ctx}/postmedia/mediainfo/uploadmediafileMore",--%>
				enableResumableUpload: true,
				uploadExtraData: {
					'uploadToken': 'SOME-TOKEN', // for access control / security
				},
				maxFileCount: 15,   				//最大上传数量
				language: 'zh',						//中文语言
				allowedFileTypes: ['image'],    	//Image图片种类			
				showUpload:false,					//是否显示上传按钮,(因为要走同步提交,所以在这里我就关闭)
                uploadAsync:false,					//false 同步上传,后台用数组接收,true 异步上传,每次上传一个file,会调用多次接口
                initialPreviewAsData: true,
				overwriteInitial: false,
				autoReplace:false,					//是否自动替换
				theme: 'fas',						//主题(我bootStrap版本可能低了,样式有点问题)
				deleteUrl: "${ctx}/postmedia/mediainfo/deletemediafile" 	//(删除路径,其实在新增信息的时候我没用到,因为我把他归类到编辑的时候去删除,不过有一点:没点保存的可以移除)
			}).on('fileuploaded', function(event,data,previewId,index) {
                imgPath=imgPath+index;
				console.log('File Uploaded', 'ID: ' + index + ', Thumb ID: ' + previewId);
				console.log(data.response);
			}).on('fileuploaderror', function(event, data, msg) {
				console.log('File Upload Error', 'ID: ' + data.fileId + ', Thumb ID: ' + data.previewId);
			}).on('filebatchuploadcomplete', function(event, data, msg) {
				console.log(imgPath,'File Batch Uploaded', data,msg);
			});//(走同步,这些压根也没用到)

//这一步也是比较重要的(在提交表单之前,去upload一下文件):
			$("#input-100").fileinput("upload");
			$("#inputForm").submit();
			
<!--  fileinput选择框 -->
<div class="row-fluid row-fluid_custom">
			<label class="control-label" style="font-size: 15px"></span>上传图片:</label>
			<p class="help-block" style="font-weight: bold">支持JPG、JPEG、PNG格式</p>
			<input type="file" id="input-100" name="files" accept="image/*" multiple>
</div>


2、(添加)后台代码

@RequestMapping(value = {"add"}, method = RequestMethod.POST)
@RequiresPermissions(value = "mediainfo:add")
public String add(TbMediaInfo dto, HttpServletRequest request,@RequestParam MultipartFile[] files, Model model){
if (StringUtils.isNotBlank(files[0].getOriginalFilename())){
				if (newId != null && newId != 0) {
					AbstractFileUtil fileUtil = FileUploadManager.builder();
					TbMediaResource mrDbDto = new TbMediaResource();
					MultipartFile[] dtoFiles = files;
					String xdPath = null;
					String fileName = null;
					for (int i = 0; i < dtoFiles.length; i++) {
						File fileFb = new File(dtoFiles[i].getOriginalFilename());
						String filePath = fileUtil.getPrefixPath(loginuser.getOrg().getDeptCode(), FileUploadContstant.MEDIA_FILE_UPLOAD_PATH, request);
						try {
							dtoFiles[i].transferTo(fileFb);
							xdPath = fileUtil.uploadFile(filePath, fileFb);
						} catch (IOException e) {
							e.printStackTrace();
							addMessage(model, "保存文件失败!");
							model.addAttribute("redirectUrl", Global.getAdminPath() + "/postmedia/mediainfo/list");
							return super.GLOBAL_ERROR;
						}
						//TODO:将文件添加到图片内存表中
						//拆分文件名
						fileName = xdPath.substring(xdPath.lastIndexOf("/")+1);
						mrDbDto.setMediaId(Long.valueOf(newId));
						mrDbDto.setName(fileName);
						mrDbDto.setPath(xdPath);
						mrDbDto.setCreateTime(new Date());
						mediaresourceService.insert(mrDbDto);
						if (i == 0){
							dto.setImgName(fileName);
							dto.setImgPath(xdPath);
							mediainfoService.update(dto);
						}
					}
				}
			}
			addMessage(model, "资源信息新增成功");
			model.addAttribute("redirectUrl", Global.getAdminPath()+"/postmedia/mediainfo/list");
			return super.GLOBAL_SUCCESS;
}
//此处只是展示局部代码,主要是看看这个传值,files就是前台的 name = “files”,这里用数组接收即可

编辑信息,(也编辑图片的信息操作)
3、(编辑)前台代码

 			var imgPath = ${ImgPaths};		 		//此处是拿到了后台查询到的关于此条信息的相关图片
            var path;
            let arrayImgPath = new Array;			//定义一个数组,因为回显图片需要用数组形式接收
            let initialPreviewConfig = new Array;	//定义一个给后台传输删除参数的数组
            $.each(imgPath, function(i) {
                path = "${sctx}/" + imgPath[i];		//在本系统里面,因这里牵扯到一个路径拼接,所以这里要做一个路径的追加
                arrayImgPath.push(path);
				initialPreviewConfig.push({key:imgPath[i]});		//这里把每个图片信息塞到数组中,(也是个初始化的过程,后面删除图片他会自动去拿数据传给后台,这里还有个属性:extra(额外传输给后台的参数,可随意定义参数名))
            });
            $("#input-100").fileinput({
				uploadUrl: "${ctx}/postmedia/mediainfo/uploadmediafile?cryptId=${cryptId}",//(在编辑信息这里,我采用的是异步,因为同步会有一些业务上的bug,这个id我是要传给后台去保存该条信息的,也就是标识这个图片是属于这个信息里面的)
				enableResumableUpload: true,
				uploadExtraData: {
					'uploadToken': 'SOME-TOKEN', // for access control / security
				},
				maxFileCount: 15,
				language: 'zh',
				allowedFileTypes: ['image'],    // allow only images
				showCancel: true,
                showPreview:true,
				showUpload:true,			//是否显示上传按钮  
				showRemove:true,			//显示移除按钮
				uploadAsync:true,			//false 同步上传,后台用数组接收,true 异步上传,每次上传一个file,会调用多次接口
				initialPreviewAsData: true,
				overwriteInitial: false,
				theme: 'fas',
				autoReplace:false,
                initialPreview:arrayImgPath,//接收历史图片,
				initialPreviewConfig:initialPreviewConfig,
				deleteUrl: "${ctx}/postmedia/mediainfo/deletemediafile"
			}).on('fileuploaded', function(event,data,previewId,index) {
				imgPath=imgPath+index;
				console.log('File Uploaded', 'ID: ' + index + ', Thumb ID: ' + previewId);
				console.log(data.response);
			}).on('fileuploaderror', function(event, data, msg) {
				console.log('File Upload Error', 'ID: ' + data.fileId + ', Thumb ID: ' + data.previewId);
			}).on('filebatchuploadcomplete', function(event, data, msg) {
				console.log(imgPath,'File Batch Uploaded', data,msg);
			}).on('filepredelete', function(event, key, jqXHR, data) {
				if(!confirm("确定删除该图片?删除后不可恢复")){
					return true;
				}
			});

4、(编辑)后台代码

//上传文件(媒介资源信息)
	@ResponseBody
	@RequestMapping(value = { "/uploadmediafile" }, method = { RequestMethod.POST })
	public Map<String, String> uploadMediaFile(Model model,String cryptId, HttpServletRequest request) {
		WebUserInfo loginuser = UserUtils.getPrincipal();

		String mediaId = AesUtils.getInstance().decrypt(loginuser.getUser().getSalt(),cryptId);
		// 转型为MultipartHttpRequest(这里取file文件的值要用这个方式来取,可能还有其他方式)
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		if (multipartRequest.getMultiFileMap().size() == 0){
			return super.renderJsonError("请选择要上传的文件!");
		}
		//获取文件(因为走异步上传,即使是选择多张照片去点击上传,它就会重复去调这个方法,所以只取数组中第一个(本来也只有一个))
		MultipartFile files = multipartRequest.getMultiFileMap().get("fileBlob").get(0);

		//上传文件(根据上传类型传入不同位置)
		if (StringUtils.isNotBlank(files.getOriginalFilename())){
				AbstractFileUtil fileUtil = FileUploadManager.builder();
				TbMediaResource mrDbDto = new TbMediaResource();
				String xdPath = null;
				String fileName = null;
				File fileFb = new File(files.getOriginalFilename());
				String filePath = fileUtil.getPrefixPath(loginuser.getOrg().getDeptCode(), FileUploadContstant.MEDIA_FILE_UPLOAD_PATH, request);
				try {
					files.transferTo(fileFb);
					xdPath = fileUtil.uploadFile(filePath, fileFb);
				} catch (IOException e) {
					e.printStackTrace();
					return super.renderJsonError("上传失败!");
				}
				//TODO:将文件添加到图片内存表中
				//拆分文件名
				fileName = xdPath.substring(xdPath.lastIndexOf("/")+1);
				mrDbDto.setMediaId(Long.valueOf(mediaId));
				mrDbDto.setName(fileName);
				mrDbDto.setPath(xdPath);
				mrDbDto.setCreateTime(new Date());
				mediaresourceService.insert(mrDbDto);
				return super.renderJsonSuccess("上传成功!");
			}
				return super.renderJsonError("文件为空!");
		}

在这里着重说一下这个request里的值,在网上看有几种接收方式,但都试了无果,在debug调试的时候看到文件存在request里面,那么直接get(“fileBlob”)就能拿到了,还必须按他的这个参数命名来取,所以就有了上述multipartRequest.getMultiFileMap().get(“fileBlob”).get(0);它以数组形式存在的,取也就取第一个。即使多张图片去走异步,它依然是重复掉这个上传方法
在这里插入图片描述
5、编辑中删除图片

 @ResponseBody
 @RequestMapping(value = {"/deletemediafile"}, method = {RequestMethod.POST})
    public Map<String, String> deleteMediaFile(String key) {
        if (StringUtils.isNotBlank(key)) {
            mediaresourceService.deleteByName(key.substring(key.lastIndexOf("/") + 1));
            return super.renderJsonSuccess("删除成功!");
        }
        return super.renderJsonSuccess("未找到数据!");
    }

注意到:在编辑页面的初始化中这次用到了deleteUrl,这个就是调后台删除的方法,initialPreviewConfig就是给后台传值的,拿到的是点击这张图片时的值,在这里回显的时候我只传了路径,所以也就直接拿它去做后台删除操作了,总之是唯一的。(在此项目中因为上传的时候做了一些封装,给名称会随机添加一些字母数字,所以永远不会重复,其实建议用id)

自此,同步和异步上传的方式大概就是这样子了,因为项目原因,目前bootStrap版本用的还是2.0+版本所以导致和fileinput的版本有些不兼容,样式简陋,害…
附图:
在这里插入图片描述
其实上传常用的属性就那几个,多试试就行了,从官方文档来看这个插件还是很成熟的,深入还需多学习,欢迎交流!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要禁用bootstrap-fileinput的选择文件按钮,你可以使用`disable`方法。具体步骤如下: 1. 在HTML中,添加一个file input元素和一个隐藏的input元素。例如: ```html <input id="file-1" type="file" name="file" class="file"> <input id="hidden-input" type="text" style="display:none;"> ``` 2. 在JavaScript中,初始化file input元素,并禁用选择文件按钮。例如: ```javascript $("#file-1").fileinput({ uploadUrl: "/upload", // 上传文件的URL uploadAsync: true, // 异步上传 showUpload: false, // 不显示上传按钮 showRemove: false, // 不显示删除按钮 showCancel: false, // 不显示取消按钮 showPreview: false, // 不显示预览区域 browseClass: "btn btn-primary", // 按钮样式 language: "zh", // 中文语言 maxFileSize: 1024, // 文件大小限制 maxFilesNum: 1, // 文件数量限制 allowedFileExtensions: ["jpg", "png", "gif"], // 文件类型限制 elErrorContainer: "#error-block" // 错误提示区域 }); $("#file-1").on("filebatchselected", function(event, files) { // 禁用选择文件按钮 $("#file-1").fileinput("disable"); // 设置隐藏的input的值 $("#hidden-input").val("1"); }); ``` 在这个例子中,当用户选择文件后,`filebatchselected`事件会触发。在事件处理程序中,你可以调用`disable`方法来禁用选择文件按钮,并设置隐藏的input的值,以便在提交表单时检查是否已选择文件。 注意:禁用选择文件按钮后,用户将无法再次选择文件,除非你启用它。你可以使用`enable`方法来启用它。例如: ```javascript $("#file-1").fileinput("enable"); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值