最近在写一个项目,用到了ajaxfileupload做为上传的插件,但在需求文档中,明确要求做到以下几点
1、可以多文件上传
2、每个文件的大小不超过20M
3、判断文件的格式。
4、上传的文件总数不能超过N个。
基于以上的要求发现我现在使用的版本根本不支持【2】【4】
于是花了一下午时间,自己瞎捣鼓了下。
html
<div class="form-body col-md-9">
<div class="form-group ">
<label style="margin-left:65px;" class="control-label col-md-1">附件 <span class="required"> </span>
</label>
<div class="col-md-6">
<input id="file_upload" name="file_upload[]" type="file" multiple="true" style="box-shadow: 0px 0px #fff" onclick = "upload(this,10)">
</div>
<label class="control-label err_msg " style="color:red">支持doc,txt,jpg,jpeg,png,xls,mp4,zip,xlsx,pdf,avi,docx格式,单个不超过20M</label>
</div>
</div>
<div class="form-body col-md-9">
<div class="form-group ">
<label style="margin-left:65px;" class="control-label col-md-1"> </label>
<div class="col-md-6 new_order_attachment">
</div>
</div>
</div>
说明:
请注意有个upload(this,10); this是指当前对象,10是支持的上传文件总个数,上传完成后会放到 new_order_attachment 这个class下
前端js:
function upload(filesObj,num){
$('input[type="file"]').ajaxfileupload({
action: '/myorder/upload/',
validate_extensions:true,
valid_extensions : ['doc','txt','jpg','jpeg','png','xls','mp4','zip','xlsx','pdf','avi','docx'],
onStart:function(evnt){
var fileCount = filesObj.files.length;
var total = $(".new_order_attachment > p").length + fileCount;
if (window.File && window.FileList && total > num){
alert("附件超过"+num+"个,请重新上传");
return false;
}
for(var i = 0; i < filesObj.files.length; i++){
if(filesObj.files[i].size > 20971520){
alert(filesObj.files[i].name + "超过20M,请重新上传");
return false;
}
}
return true;
},
onComplete: function(json_data,response) {
if(parseInt(json_data.code) == 1){
$(".new_order_attachment").append(json_data.data);
}else{
if(typeof(json_data.msg) == "undefined" || json_data.msg == "undefined"){
json_data.msg = json_data.message;
}
alert(json_data.msg);
}
},
onCancel: function() {
}
});
}
说明:
onStart中检测了用户已经上传的文件个数,上传时每个文件的大小
onComplete中对返回的undefined进行处理
ajaxfileupload源码改动
/*
// jQuery Ajax File Uploader
//
// @author: Jordan Feldstein <jfeldstein.com>
//
// - Ajaxifies an individual <input type="file">
// - Files are sandboxed. Doesn't matter how many, or where they are, on the page.
// - Allows for extra parameters to be included with the file
// - onStart callback can cancel the upload by returning false
*/
(function($) {
$.fn.ajaxfileupload = function(options) {
var settings = {
params: {},
action: '',
onBefore: function() { },
onStart: function() { },
onComplete: function(response) { },
onCancel: function() { },
validate_extensions : false,
valid_extensions : ['gif','png','jpg','jpeg'],
submit_button : null
};
var uploading_file = false;
if ( options ) {
$.extend( settings, options );
}
// 'this' is a jQuery collection of one or more (hopefully)
// file elements, but doesn't check for this yet
return this.each(function() {
var $element = $(this);
// Skip elements that are already setup. May replace this
// with uninit() later, to allow updating that settings
if($element.data('ajaxUploader-setup') === true) return;
$element.change(function()
{
// since a new image was selected, reset the marker
uploading_file = false;
// only update the file from here if we haven't assigned a submit button
if (settings.submit_button == null)
{
upload_file();
}
});
if (settings.submit_button == null)
{
// do nothing
} else
{
settings.submit_button.click(function(e)
{
// Prevent non-AJAXy submit
e.preventDefault();
// only attempt to upload file if we're not uploading
if (!uploading_file)
{
upload_file();
}
});
}
var upload_file = function()
{
if($element.val() == '') return settings.onCancel.apply($element, [settings.params]);
// make sure extension is valid
var ext = $element.val().split('.').pop().toLowerCase();
if(true === settings.validate_extensions && $.inArray(ext, settings.valid_extensions) == -1)
{
// Pass back to the user
settings.onComplete.apply($element, [{status: false, message: '格式不正确,请重新上传'}, settings.params]);
} else
{
uploading_file = true;
// Creates the form, extra inputs and iframe used to
// submit / upload the file
// Call user-supplied (or default) onStart(), setting
// it's this context to the file DOM element
var ret = settings.onStart.apply($element, [settings.params]);
// let onStart have the option to cancel the upload
if(ret !== false)
{
wrapElement($element);
$element.parent('form').submit(function(e) { e.stopPropagation(); }).submit();
} else {
uploading_file = false;
}
}
};
// Mark this element as setup
$element.data('ajaxUploader-setup', true);
/*
// Internal handler that tries to parse the response
// and clean up after ourselves.
*/
var handleResponse = function(loadedFrame, element) {
var response, responseStr = $(loadedFrame).contents().text();
try {
//response = $.parseJSON($.trim(responseStr));
response = JSON.parse(responseStr);
} catch(e) {
response = responseStr;
}
// Tear-down the wrapper form
element.siblings().remove();
element.unwrap();
uploading_file = false;
// Pass back to the user
settings.onComplete.apply(element, [response, settings.params]);
};
/*
// Wraps element in a <form> tag, and inserts hidden inputs for each
// key:value pair in settings.params so they can be sent along with
// the upload. Then, creates an iframe that the whole thing is
// uploaded through.
*/
var wrapElement = function(element) {
// Create an iframe to submit through, using a semi-unique ID
var frame_id = 'ajaxUploader-iframe-' + Math.round(new Date().getTime() / 1000)
$('body').after('<iframe width="0" height="0" style="display:none;" name="'+frame_id+'" id="'+frame_id+'"/>');
$('#'+frame_id).get(0).onload = function() {
handleResponse(this, element);
};
// Wrap it in a form
element.wrap(function() {
return '<form action="' + settings.action + '" method="POST" enctype="multipart/form-data" target="'+frame_id+'" />'
})
// Insert <input type='hidden'>'s for each param
.before(function() {
var key, html = '';
for(key in settings.params) {
var paramVal = settings.params[key];
if (typeof paramVal === 'function') {
paramVal = paramVal();
}
html += '<input type="hidden" name="' + key + '" value="' + paramVal + '" />';
}
return html;
});
}
});
}
})( jQuery )
最后总结:
现在的程序员,js不强都没办法生活。