深入学习jquery源码之上传附件插件的实现
/**
* 上传附件通用JS (基于layerUI)
*/
;(function($){
var defaults = {
url : "/attach/upload",
fieldCode : "aboutDocument", //业务字段编码
fieldName : "相关文件", //业务字段名称
entityName : "template", //业务实体
};
function renderUpload(options){
this.settings = $.extend({},defaults,options);
this.settings.elem = "#" + this.settings.fieldCode;
this.settings.bindAction = "#" + this.settings.fieldCode + "_Action"; //上传操作按钮
this.settings.layuiUploadPreview = "#"+ this.settings.fieldCode +"_preview";
this.settings.previewTableBody = "#"+ this.settings.fieldCode +"_Preview_Table"; //上传预览表格
this.init();
}
//为函数添加原型链上的方法
renderUpload.prototype = {
init: function(){
var that = this;
var uploadInst = layui.upload.render({
elem: that.settings.elem //绑定元素
,url: CONTEXT_PATH + that.settings.url //上传接口
,accept:'file'
,data:{ //上传参数
"entityName" : that.settings.entityName, //业务实体
"fieldCode" : that.settings.fieldCode, //业务字段编码
"fieldName" : that.settings.fieldName, //业务字段名称
}
,auto:false //是否选完文件后自动上传 如果设定 false,那么需要设置 bindAction 参数来指向一个其它按钮提交上传
,size:0 //设置文件最大可允许上传的大小,单位 KB。不支持ie8/9; 0(即不限制)
,multiple:true
//是否允许多文件上传。设置 true即可开启。不支持ie8/9
,bindAction: that.settings.bindAction //指向一个按钮触发上传,一般配合 auto: false 来使用。值为选择器或DOM对象,如:bindAction: '#btn'
,choose: function(res){ //选择文件后的回调函数
var layIndex = layer.open({
type: 1,
title: "预览",
maxmin: false,
area : ['40%', '40%'],
content:$(that.settings.layuiUploadPreview).removeAttr('style'), //$.loadHtml(preUrl),
success: function(layero){
var demoListView = $(that.settings.previewTableBody).empty();
var files = that.settings.selfFiles = res.pushFile(); //将每次选择的文件追加到文件队列
//读取本地文件
res.preview(function(index, file, result){
var tr = $(['' '].join(''));
,''+ file.name +' '
,''+ (file.size/1024).toFixed(1) +' kb '
,'等待上传 '
,'' '
,''
,''
,'
,'
//单个重传
tr.find('.demo-reload').on('click', function(){
res.upload(index, file);
});
//删除
tr.find('.demo-delete').on('click', function(){
delete files[index]; //删除对应的文件
tr.remove();
uploadInst.config.elem.next()[0].value = ''; //清空 input file 值,以免删除后出现同名文件不可选
if(Object.getOwnPropertyNames(files).length == 0){ //当上传预览没有文件时,关闭弹出框
layer.close(layIndex);
}
});
demoListView.append(tr);
});
},
end : function(){ //layer销毁回调
$(that.settings.layuiUploadPreview).attr('style','display:none;');
$(that.settings.previewTableBody).empty();
},
cancel: function(){ //右上角关闭回调
}
});
}
,before: function(res){ //文件提交上传前的回调
$("tr",$(that.settings.previewTableBody)).find("td[name='upload-status']").text("上传中...");
}
,done: function(res, index, upload){ //执行上传请求后的回调。返回三个参数,分别为:res(服务端响应信息)、index(当前文件的索引)、upload(重新上传的方法,一般在文件上传失败后使用)
//上传完毕回调 "dealPicture_list_table"
if(res && res.status == WebConst.SUCCESS){
$(that.settings.bindAction).text("").text("上传成功");
delete that.settings.selfFiles[index];
//改变预览状态,将上传附件id存在 隐藏域中
$("tr[id='upload-"+ index +"']",$(that.settings.previewTableBody)).find("td[name='upload-status']").text("附件缓存完毕,请点击提交上传附件");
var unupload = $("#uploadAttachmentIds").data("uploadAttachmentIds");
if(unupload){
unupload.push(res.data['attachmentId']);
$("#uploadAttachmentIds").data("uploadAttachmentIds",unupload);
}else{
if(res.data){
$("#uploadAttachmentIds").data("uploadAttachmentIds",[res.data['attachmentId']]);
/**
* 第一个方法赋不了值,通过下面的赋值
*/
$("#uploadAttachmentIds").val([res.data['attachmentId']]);
}
}
//处理卡片页面列表展示问题
var afile = res.data;
var attachImg = "";
if(!$.isEmptyStr(afile.fileName) && (afile.fileName.indexOf('docx')!=-1
|| afile.fileName.indexOf('doc')!=-1))
{
//attachImg = '';
attachImg = '';
}
else if(!$.isEmptyStr(afile.fileName) && afile.fileName.indexOf('pdf')!=-1)
{
attachImg = '';
}
else
{
attachImg = '';
}
var $tr = $(['' '].join(''));
, attachImg
,''+ afile.fileName +' '
,''+ afile.fileSize +' kb '
,''+ afile.createDate +' '
,'' '
,'下载 '
,''
,'
,'
$tr.find('button').on('click',function(){
var attId = $(this).closest("tr").attr('attatchmentId');
var url = CONTEXT_PATH + '/attach/delete/datafile';
var rlt = $.getData(url,{'attachmentIds':attId});
if(rlt && rlt.status == WebConst.SUCCESS){
$(this).closest("tr").remove();
$("#uploadAttachmentIds").data("uploadAttachmentIds").removeByValue(attId);
}
return false;
});
$("#" + afile.fieldCode + "_list_table").append($tr);
}
}
,error: function(index, upload){ //执行上传请求出现异常的回调(一般为网络异常、URL 404等)。返回两个参数,分别为:index(当前文件的索引)、upload(重新上传的方法)
//请求异常回调
}
});
}
}
//扩展jquery类方法
$.extend({
renderUpload : function(options){
return new renderUpload(options);
}
});
})(jQuery);
如何使用:
html
@uploadPlugin>
freemarker的后台配置
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
/view
10
zh_CN
yyyy-MM-dd HH:mm:ss
yyyy-MM-dd
#.##
text/html;charset=UTF-8
com.framework.web.view.CntenFreeMarkerView
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import freemarker.core.Environment;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
/**
* 附件上传组件
* @author Administrator
*/
@Component
public class UploadPluginDirective implements TemplateDirectiveModel{
@Override
public void execute(Environment env, @SuppressWarnings("rawtypes") Map params, TemplateModel[] loopVars,
TemplateDirectiveBody body) throws TemplateException, IOException {
SimpleScalar fieldCode = (SimpleScalar) params.get("fieldCode"); //上传附件编码
SimpleScalar fieldName = (SimpleScalar) params.get("fieldName"); //上传附件名称
SimpleScalar editable = (SimpleScalar) params.get("editable");
Writer out = env.getOut();
if (fieldCode != null && fieldName != null) {
StringBuilder builder = new StringBuilder();
builder.append("");
builder.append("")")
.append(" ")
.append("");")
if(editable != null && StringUtils.isEmpty(editable.getAsString())) {
builder.append(" ");
}
builder.append("")")
.append("")")
.append("")
")
.append(" ")
.append("") 缩略图 ")
.append("文件名 ")
.append("文件大小 ")
.append("上传时间 ")
.append("操作 ")
.append("
.append(" ")
.append("
.append("
.append("
.append("
.append("
.append("")
.append("")")
.append("")")
.append("")
")
.append(" ")
.append("") 文件名 ")
.append("大小 ")
.append("状态 ")
.append("操作 ")
.append("
.append(" ")
.append("
.append("
.append(" ")
.append("
.append("")
.append("");
out.write(builder.toString());
}else {
out.write("freemarker自定义命令初始化参数缺失...");
}
if(body != null) {
body.render(out);
}else {
throw new RuntimeException("freemarker自定义标签内部至少要加一个空格");
}
}
}
js 执行实例调用附件上传
//执行实例
$.renderUpload({
fieldName : "上传附件", //业务字段名称
fieldCode : "dealPicture", //业务字段编码
entityName : "add", //业务实体
selfFiles : _self.files
});
var ShowNews = CardPager.extend({
init: function(filter, url){
this._super(filter, url);
//界面需要引用的插件
this.plugins = ['element', 'form', 'layedit', 'upload', 'laydate', 'layer'];
this.primaryKey = "newsId";
this.primaryValue = $.QueryString("entityId");
this.dataUrl = CONTEXT_PATH + '/gasNews/get';
this.entityName = "news";
},
initLayuiPlugin: function(){
this._super();
var _self = this;
_self.files = null;
//执行实例
$.renderUpload({
fieldName : "上传附件", //业务字段名称
fieldCode : "dealPicture", //业务字段编码
entityName : "news", //业务实体
selfFiles : _self.files
});
},
initEvent: function(){
this._super();
var _self = this;
//TODO 父类只定义了 保存事件,其他事件在这里进行定义
},
initThirdPlugin: function(){
var _self = this;
KindEditor.ready(function(K) {
_self.gasNewsContent = K.create('#newsContent');
});
}
});
$(function(){
showNews = new ShowGasNews('news', CONTEXT_PATH + '/news/save');
showNews.render();
//关闭卡片页面之前回调
function beforeClose (){
//如果涉及到文件上传,关闭卡片页面将未上传的附件进行删除
var unuploadFiles = $("#uploadAttachmentIds").data("uploadAttachmentIds");
if(unuploadFiles && unuploadFiles.length>0){
var url = CONTEXT_PATH + '/attach/delete/datafile';
$.getData(url,{'attachmentIds':unuploadFiles.join(",")});
}
}
});
查看图片回显
(function(scope){
var CardPager = Class.extend({
init: function(filter, url){
this.filter = filter;
this.url = url;
},
render: function(){
var _self = this;
_self.initThirdPlugin(); //初始化第三放插件
//plugins 这个可以不传,但是请不要传空数组过来
var plugins = _self.plugins || ['form'];
layui.use(plugins,function(){
_self.initEvent();
_self.initLayuiPlugin(); //初始化layui组件
//渲染表单数据
var params = {};
params[_self.primaryKey] = _self.primaryValue;
$.ajaxReq(_self.dataUrl, params, function(data){
if(data && data.status == WebConst.SUCCESS && data.data){
var cardForm = $("#"+_self.filter+"Form"),
formDoms = cardForm[0];
cardForm.setValues(data.data);
//处理富文本赋值问题
for(i=0,len=formDoms.length; ivar idom = formDoms[i],
idomName = idom.name,
tagName = idom.tagName,
idomId = idom.id,
keditor = _self[idomName];
if(idom.tagName == "TEXTAREA" && keditor){
keditor.html(data.data[idomName]);
}
}
layui.form.render();
}
},WebConst.AJAX_FORM,null,false);
});
_self.initFiles();
},
//附件上传查看图片回显
initFiles: function(){
var _self = this,
attachParam = {};
attachParam.entityId = _self.primaryValue;
attachParam.entityName = _self.entityName;
$.ajaxReq(CONTEXT_PATH + "/attach/entity/files", attachParam, function(data){
if(data && data.status == WebConst.SUCCESS && data.data){
var files = data.data;
$("div[class='layui-upload']").each(function(index,obj){
var containerId = $(obj).attr('id'),
attachField = containerId.split("_")[0],
tableBody = containerId + "_table";
for(var i=0,len=files.length; ivar cFile = files[i];
if(cFile.fieldCode == attachField){
var $tr = $(['' '].join(''));
,''
,''+ cFile.fileName +' '
,''+ cFile.fileSize +' kb '
,''+ cFile.createDate +' '
,'' '
,'下载 '
,''
,'
,'
$tr.find('button').on('click',function(){
var rlt = $.getData(CONTEXT_PATH + "/attach/delete/updflag",{'attachmentId':$(this).closest("tr").attr('attatchmentId')});
if(rlt && rlt.status == '1000'){
$(this).closest("tr").remove();
}
return false;
});
$("#" + tableBody).append($tr);
}
}
})
}
},WebConst.AJAX_FORM,null,false);
},
initThirdPlugin: function(){
},
initLayuiPlugin: function(){
var _self = this;
},
initEvent: function(){
var _self = this;
layui.form.on('submit(' + _self.filter + ')', function(data){
//处理 KindEditor 富文本取值问题
var formDoms = data["form"];
for(i=0,len=formDoms.length; ivar idom = data["form"][i],
idomName = data["form"][i].name,
tagName = idom.tagName,
idomId = data["form"][i].id,
keditor = _self[idomName];
if(idom.tagName == "TEXTAREA" && keditor){
keditor.sync();
data.field[idomName] = $('#'+idomId ).val(); // jQuery
}
}
var retData = $.getData(_self.url, data.field);
if(retData.status == WebConst.FAIL){
layer.msg('保存失败', {icon: 5});
return false;
}
//如果有附件,上传附件
var uploadAttachmentIds = $("#uploadAttachmentIds").data("uploadAttachmentIds"),
entityId = retData.data;
$("input[name='"+ _self.primaryKey +"']").val(retData.data);
if(true && uploadAttachmentIds && entityId){
var params = {};
params.attachmentIds = uploadAttachmentIds.join(",");
params.entityId = entityId;
$.getData(CONTEXT_PATH + "/attach/updateEntityId", params);
}
$("#uploadAttachmentIds").data("uploadAttachmentIds",null);
layer.msg('保存成功', {icon: 6});
return false;
});
}
});
scope.CardPager = CardPager;
})(window);