Javascript
input 파일 다중 업로드 (MultiFile plugin)
- 2024.12.20 09:36:59
[!]html[/!]
<input type="file" name="attach" id="attach">
<div class="attaedbox"></div> <script type="text/javascript"> $(':file[name=attach]').MultiFile({ 'max' : 5, 'accept' : 'gif|jpg|jpeg|bmp|png|pdf', 'maxfile' : 10240, //각 파일 최대 업로드 크기 (kb) 'list' : $('.attaedbox'), //파일목록을 출력할 요소 지정가능 'STRING' : { // error문구를 원하는대로 수정 'remove' : "<a href=\"#\" class=\"remove\">제거</a>", 'duplicate' : "$file 은 이미 선택된 파일입니다.", 'denied' : "$ext 는(은) 업로드 할수 없는 파일확장자입니다.", 'selected' :'$file 을 선택했습니다.', 'toomuch' : "업로드할 수 있는 최대크기를 초과하였습니다.($size)", 'toomany' : "업로드할 수 있는 최대 개수는 $max개 입니다.", 'toobig' : "$file 은 크기가 매우 큽니다. (max $size)" } }); </script> [!]css[/!] .MultiFile-wrap {min-height: 52px;display: flex;align-items: center;}
.MultiFile-label + .MultiFile-label {margin-top: 2px;} .MultiFile-label {display: flex;align-items: center;} .MultiFile-label > .remove {margin-right: 10px;width: 40px;height: 25px;line-height: 23px;box-sizing: border-box;border: 1px solid #ccc;border-radius: 3px;text-align: center;font-size: 12px;color: #333;background: #fff;} [!]jquery[/!] /* jquery-multifile v2.2.2 @ 2020-04-16 06:05:29 */
window.jQuery&&function(d){"use strict";function g(e){return 1048576<e?(e/1048576).toFixed(1)+"Mb":1024==e?"1Mb":(e/1024).toFixed(1)+"Kb"}function h(e){return(e.files&&e.files.length?e.files:null)||[{name:e.value,size:0,type:((e.value||"").match(/[^\.]+$/i)||[""])[0]}]}d.fn.MultiFile=function(e){if(0==this.length)return this;if("string"==typeof arguments[0]){if(1<this.length){var i=arguments;return this.each(function(){d.fn.MultiFile.apply(d(this),i)})}return d.fn.MultiFile[arguments[0]].apply(this,d.makeArray(arguments).slice(1)||[])}"number"==typeof e&&(e={max:e});e=d.extend({},d.fn.MultiFile.options,e||{});d("form").not("MultiFile-intercepted").addClass("MultiFile-intercepted").submit(d.fn.MultiFile.disableEmpty),d.fn.MultiFile.options.autoIntercept&&(d.fn.MultiFile.intercept(d.fn.MultiFile.options.autoIntercept),d.fn.MultiFile.options.autoIntercept=null),this.not(".MultiFile-applied").addClass("MultiFile-applied").each(function(){window.MultiFile=(window.MultiFile||0)+1;var i=window.MultiFile,f={e:this,E:d(this),clone:d(this).clone()},c=d.extend({},d.fn.MultiFile.options,e||{},(d.metadata?f.E.metadata():d.meta?f.E.data():null)||{},{});0<c.max||(c.max=f.E.attr("maxlength")),0<c.max||(c.max=(String(f.e.className.match(/\b(max|limit)\-([0-9]+)\b/gi)||[""]).match(/[0-9]+/gi)||[""])[0],0<c.max?c.max=String(c.max).match(/[0-9]+/gi)[0]:c.max=-1),c.max=new Number(c.max),c.accept=c.accept||f.E.attr("accept")||"",c.accept&&c.accept.match(/\//)&&(c.accept=""),c.accept||(c.accept=f.e.className.match(/\b(accept\-[\w\|]+)\b/gi)||"",c.accept=new String(c.accept).replace(/^(accept|ext)\-/i,"")),c.maxsize=0<c.maxsize?c.maxsize:f.E.data("maxsize")||0,0<c.maxsize||(c.maxsize=(String(f.e.className.match(/\b(maxsize|maxload|size)\-([0-9]+)\b/gi)||[""]).match(/[0-9]+/gi)||[""])[0],0<c.maxsize?c.maxsize=String(c.maxsize).match(/[0-9]+/gi)[0]:c.maxsize=-1),c.maxfile=0<c.maxfile?c.maxfile:f.E.data("maxfile")||0,0<c.maxfile||(c.maxfile=(String(f.e.className.match(/\b(maxfile|filemax)\-([0-9]+)\b/gi)||[""]).match(/[0-9]+/gi)||[""])[0],0<c.maxfile?c.maxfile=String(c.maxfile).match(/[0-9]+/gi)[0]:c.maxfile=-1),1<c.maxfile&&(c.maxfile=1024*c.maxfile),1<c.maxsize&&(c.maxsize=1024*c.maxsize),!1!==c.multiple&&1<c.max&&f.E.attr("multiple","multiple").prop("multiple",!0),d.extend(f,c||{}),f.STRING=d.extend({},d.fn.MultiFile.options.STRING,f.STRING),d.extend(f,{n:0,slaves:[],files:[],instanceKey:f.e.id||"MultiFile"+String(i),generateID:function(e){return f.instanceKey+(0<e?"_F"+String(e):"")},trigger:function(e,t,a,i){var l,n=a[e]||a["on"+e];if(n)return i=i||a.files||h(this),d.each(i,function(e,i){l=n.apply(a.wrapper,[t,i.name,a,i])}),l}}),1<String(f.accept).length&&(f.accept=f.accept.replace(/\W+/g,"|").replace(/^\W|\W$/g,""),f.rxAccept=new RegExp("\\.("+(f.accept||"")+")$","gi")),f.wrapID=f.instanceKey,f.E.wrap('<div class="MultiFile-wrap" id="'+f.wrapID+'"></div>'),f.wrapper=d("#"+f.wrapID),f.e.name=f.e.name||"file"+i+"[]",f.list||(f.wrapper.append('<div class="MultiFile-list" id="'+f.wrapID+'_list"></div>'),f.list=d("#"+f.wrapID+"_list")),f.list=d(f.list),f.addSlave=function(u,m){var e;f.n++,u.MultiFile=f,u.id=u.name="",u.id=f.generateID(m),u.name=String(f.namePattern.replace(/\$name/gi,d(f.clone).attr("name")).replace(/\$id/gi,d(f.clone).attr("id")).replace(/\$g/gi,i).replace(/\$i/gi,m)),0<f.max&&f.files.length>f.max&&(e=u.disabled=!0),f.current=u,(u=d(u)).val("").attr("value","")[0].value="",u.addClass("MultiFile-applied"),u.change(function(e,i,t){d(this).blur();var r=this,a=f.files||[],l=this.files||[{name:this.value,size:0,type:((this.value||"").match(/[^\.]+$/i)||[""])[0]}],n=[],s=0,c=f.total_size||0,o=[];d.each(l,function(e,i){n[n.length]=i}),f.trigger("FileSelect",this,f,n),d.each(l,function(e,i){function a(e){return e.replace("$ext",String(l.match(/[^\.]+$/i)||"")).replace("$file",l.match(/[^\/\\]+$/gi)).replace("$size",g(t)+" > "+g(f.maxfile))}var l=i.name.replace(/^C:\\fakepath\\/gi,""),t=i.size;f.accept&&l&&!l.match(f.rxAccept)&&(o[o.length]=a(f.STRING.denied),f.trigger("FileInvalid",this,f,[i])),d(f.wrapper).find("input[type=file]").not(r).each(function(){d.each(h(this),function(e,i){var t;i.name&&(t=(i.name||"").replace(/^C:\\fakepath\\/gi,""),l!=t&&l!=t.substr(t.length-l.length)||(o[o.length]=a(f.STRING.duplicate),f.trigger("FileDuplicate",r,f,[i])))})}),0<f.maxfile&&0<t&&t>f.maxfile&&(o[o.length]=a(f.STRING.toobig),f.trigger("FileTooBig",this,f,[i]));var n=f.trigger("FileValidate",this,f,[i]);n&&""!=n&&(o[o.length]=a(n)),s+=i.size}),c+=s,n.size=s,n.total=c,n.total_length=n.length+a.length,0<f.max&&a.length+l.length>f.max&&(o[o.length]=f.STRING.toomany.replace("$max",f.max),f.trigger("FileTooMany",this,f,n)),0<f.maxsize&&c>f.maxsize&&(o[o.length]=f.STRING.toomuch.replace("$size",g(c)+" > "+g(f.maxsize)),f.trigger("FileTooMuch",this,f,n));var p=d(f.clone).clone();if(p.addClass("MultiFile"),0<o.length)return f.error(o.join("\n\n")),f.n--,f.addSlave(p[0],m),u.parent().prepend(p),u.remove(),!1;f.total_size=c,(l=a.concat(n)).size=c,l.size_label=g(c),f.files=l,d(this).css({position:"absolute",top:"-3000px"}),u.after(p),f.addSlave(p[0],m+1),f.addToList(this,m,n),f.trigger("afterFileSelect",this,f,n)}),d(u).data("MultiFile-wrap",f.wrapper),d(f.wrapper).data("MultiFile",f),e&&d(u).attr("disabled","disabled").prop("disabled",!0)},f.addToList=function(r,e,i){f.trigger("FileAppend",r,f,i);var s=d("<span/>");d.each(i,function(e,t){var i=String(t.name||"").replace(/[&<>'"]/g,function(e){return"&#"+e.charCodeAt()+";"}),a=f.STRING,l=a.label||a.file||a.name,n=a.title||a.tooltip||a.selected,a="image/"==t.type.substr(0,6)?'<img class="MultiFile-preview" style="'+f.previewCss+'"/>':"",a=d(('<span class="MultiFile-label" title="'+n+'"><span class="MultiFile-title">'+l+"</span>"+(f.preview||d(r).is(".with-preview")?a:"")+"</span>").replace(/\$(file|name)/gi,(i.match(/[^\/\\]+$/gi)||[i])[0]).replace(/\$(ext|extension|type)/gi,(i.match(/[^\.]+$/gi)||[""])[0]).replace(/\$(size)/gi,g(t.size||0)).replace(/\$(preview)/gi,a).replace(/\$(i)/gi,e));a.find("img.MultiFile-preview").each(function(){var i=this,e=new FileReader;e.readAsDataURL(t),e.onload=function(e){i.src=e.target.result}}),0<e&&c.separator&&s.append(c.separator),s.append(a);i=String(t.name||"");s[s.length]=('<span class="MultiFile-title" title="'+f.STRING.selected+'">'+f.STRING.file+"</span>").replace(/\$(file|name)/gi,(i.match(/[^\/\\]+$/gi)||[i])[0]).replace(/\$(ext|extension|type)/gi,(i.match(/[^\.]+$/gi)||[""])[0]).replace(/\$(size)/gi,g(t.size||0)).replace(/\$(i)/gi,e)});var t=d('<div class="MultiFile-label"></div>'),a=d('<a class="MultiFile-remove" href="#'+f.wrapID+'">'+f.STRING.remove+"</a>").click(function(){var e=h(r);f.trigger("FileRemove",r,f,e),f.n--,f.current.disabled=!1,d(r).remove(),d(this).parent().remove(),d(f.current).css({position:"",top:""}),d(f.current).reset().val("").attr("value","")[0].value="";var t=[],a=0;return d(f.wrapper).find("input[type=file]").each(function(){d.each(h(this),function(e,i){i.name&&(t[t.length]=i,a+=i.size)})}),f.files=t,f.total_size=a,f.size_label=g(a),d(f.wrapper).data("MultiFile",f),f.trigger("afterFileRemove",r,f,e),f.trigger("FileChange",f.current,f,t),!1});f.list.append(t.append(a," ",s)),f.trigger("afterFileAppend",r,f,i),f.trigger("FileChange",r,f,f.files)},f.MultiFile||f.addSlave(f.e,0),f.n++})},d.extend(d.fn.MultiFile,{data:function(){var e=d(this),e=e.is(".MultiFile-wrap")?e:e.data("MultiFile-wrap");if(!e||!e.length)return!console.error("Could not find MultiFile control wrapper");e=e.data("MultiFile");return e?e||{}:!console.error("Could not find MultiFile data in wrapper")},reset:function(){var e=this.MultiFile("data");return e&&d(e.list).find("a.MultiFile-remove").click(),d(this)},files:function(){var e=this.MultiFile("data");return e?e.files||[]:!console.log("MultiFile plugin not initialized")},size:function(){var e=this.MultiFile("data");return e?e.total_size||0:!console.log("MultiFile plugin not initialized")},count:function(){var e=this.MultiFile("data");return e?e.files&&e.files.length||0:!console.log("MultiFile plugin not initialized")},disableEmpty:function(e){e=("string"==typeof e?e:"")||"mfD";var i=[];return d("input:file.MultiFile").each(function(){""==d(this).val()&&(i[i.length]=this)}),window.clearTimeout(d.fn.MultiFile.reEnableTimeout),d.fn.MultiFile.reEnableTimeout=window.setTimeout(d.fn.MultiFile.reEnableEmpty,500),d(i).each(function(){this.disabled=!0}).addClass(e)},reEnableEmpty:function(e){return d("input:file."+(e=("string"==typeof e?e:"")||"mfD")).removeClass(e).each(function(){this.disabled=!1})},intercepted:{},intercept:function(e,i,t){var a,l;if((t=t||[]).constructor.toString().indexOf("Array")<0&&(t=[t]),"function"==typeof e)return d.fn.MultiFile.disableEmpty(),l=e.apply(i||window,t),setTimeout(function(){d.fn.MultiFile.reEnableEmpty()},1e3),l;e.constructor.toString().indexOf("Array")<0&&(e=[e]);for(var n=0;n<e.length;n++)(a=e[n]+"")&&function(e){d.fn.MultiFile.intercepted[e]=d.fn[e]||function(){},d.fn[e]=function(){return d.fn.MultiFile.disableEmpty(),l=d.fn.MultiFile.intercepted[e].apply(this,arguments),setTimeout(function(){d.fn.MultiFile.reEnableEmpty()},1e3),l}}(a)}}),d.fn.MultiFile.options={accept:"",max:-1,maxfile:-1,maxsize:-1,namePattern:"$name",preview:!1,previewCss:"max-height:100px; max-width:100px;",separator:", ",STRING:{remove:"x",denied:"You cannot select a $ext file.\nTry again...",file:"$file",selected:"File selected: $file",duplicate:"This file has already been selected:\n$file",toomuch:"The files selected exceed the maximum size permited ($size)",toomany:"Too many files selected (max: $max)",toobig:"$file is too big (max $size)"},autoIntercept:["submit","ajaxSubmit","ajaxForm","validate","valid"],error:function(e){"undefined"!=typeof console&&console.log(e),alert(e)}},d.fn.reset=d.fn.reset||function(){return this.each(function(){try{this.reset()}catch(e){}})},d(function(){d("input[type=file].multi").MultiFile()})}(jQuery); /* ### jQuery Multiple File Selection Plugin v2.2.2 - 2016-06-16 ### * Home: https://multifile.fyneworks.com/ * Code: https://github.com/fyneworks/multifile * * Licensed under http://en.wikipedia.org/wiki/MIT_License */ /*# AVOID COLLISIONS #*/ ; if (window.jQuery)(function ($) { "use strict"; /*# AVOID COLLISIONS #*/ // size label function (shows kb and mb where accordingly) function sl(x) { return x > 1048576 ? (x / 1048576).toFixed(1) + 'Mb' : (x==1024?'1Mb': (x / 1024).toFixed(1) + 'Kb' ) }; // utility function to return an array of function FILE_LIST(x){ return ((x.files&&x.files.length) ? x.files : null) || [{ name: x.value, size: 0, type: ((x.value || '').match(/[^\.]+$/i) || [''])[0] }]; }; // plugin initialization $.fn.MultiFile = function (options) { if (this.length == 0) return this; // quick fail // Handle API methods if (typeof arguments[0] == 'string') { // Perform API methods on individual elements if (this.length > 1) { var args = arguments; return this.each(function () { $.fn.MultiFile.apply($(this), args); }); }; // Invoke API method handler (and return whatever it wants to return) return $.fn.MultiFile[arguments[0]].apply(this, $.makeArray(arguments).slice(1) || []); }; // Accept number if (typeof options == 'number') { options = {max: options}; }; // Initialize options for this call var options = $.extend({} /* new object */ , $.fn.MultiFile.options /* default options */ , options || {} /* just-in-time options */ ); // Empty Element Fix!!! // this code will automatically intercept native form submissions // and disable empty file elements $('form') .not('MultiFile-intercepted') .addClass('MultiFile-intercepted') .submit($.fn.MultiFile.disableEmpty); //### http://plugins.jquery.com/node/1363 // utility method to integrate this plugin with others... if ($.fn.MultiFile.options.autoIntercept) { $.fn.MultiFile.intercept($.fn.MultiFile.options.autoIntercept /* array of methods to intercept */ ); $.fn.MultiFile.options.autoIntercept = null; /* only run this once */ }; // loop through each matched element this .not('.MultiFile-applied') .addClass('MultiFile-applied') .each(function () { //##################################################################### // MAIN PLUGIN FUNCTIONALITY - START //##################################################################### // BUG 1251 FIX: http://plugins.jquery.com/project/comments/add/1251 // variable group_count would repeat itself on multiple calls to the plugin. // this would cause a conflict with multiple elements // changes scope of variable to global so id will be unique over n calls window.MultiFile = (window.MultiFile || 0) + 1; var group_count = window.MultiFile; // Copy parent attributes - Thanks to Jonas Wagner // we will use this one to create new input elements var MultiFile = { e: this, E: $(this), clone: $(this).clone() }; //=== //# USE CONFIGURATION var o = $.extend({}, $.fn.MultiFile.options, options || {}, ($.metadata ? MultiFile.E.metadata() : ($.meta ? MultiFile.E.data() : null)) || {}, /* metadata options */ {} /* internals */ ); // limit number of files that can be selected? if (!(o.max > 0) /*IsNull(MultiFile.max)*/ ) { o.max = MultiFile.E.attr('maxlength'); }; if (!(o.max > 0) /*IsNull(MultiFile.max)*/ ) { o.max = (String(MultiFile.e.className.match(/\b(max|limit)\-([0-9]+)\b/gi) || ['']).match(/[0-9]+/gi) || [''])[0]; if (!(o.max > 0)) o.max = -1; else o.max = String(o.max).match(/[0-9]+/gi)[0]; }; o.max = new Number(o.max); // limit extensions? o.accept = o.accept || MultiFile.E.attr('accept') || ''; // ignore mime-type accept attribute for browser handling // see https://github.com/fyneworks/multifile/issues/101 if(o.accept && o.accept.match(/\//)) o.accept = ''; if (!o.accept) { o.accept = (MultiFile.e.className.match(/\b(accept\-[\w\|]+)\b/gi)) || ''; o.accept = new String(o.accept).replace(/^(accept|ext)\-/i, ''); }; // limit total pay load size o.maxsize = o.maxsize>0?o.maxsize:null || MultiFile.E.data('maxsize') || 0; if (!(o.maxsize > 0) /*IsNull(MultiFile.maxsize)*/ ) { o.maxsize = (String(MultiFile.e.className.match(/\b(maxsize|maxload|size)\-([0-9]+)\b/gi) || ['']).match(/[0-9]+/gi) || [''])[0]; if (!(o.maxsize > 0)) o.maxsize = -1; else o.maxsize = String(o.maxsize).match(/[0-9]+/gi)[0]; }; // limit individual file size o.maxfile = o.maxfile>0?o.maxfile:null || MultiFile.E.data('maxfile') || 0; if (!(o.maxfile > 0) /*IsNull(MultiFile.maxfile)*/ ) { o.maxfile = (String(MultiFile.e.className.match(/\b(maxfile|filemax)\-([0-9]+)\b/gi) || ['']).match(/[0-9]+/gi) || [''])[0]; if (!(o.maxfile > 0)) o.maxfile = -1; else o.maxfile = String(o.maxfile).match(/[0-9]+/gi)[0]; }; //=== // size options are accepted in kylobytes, so multiple them by 1024 if(o.maxfile>1) o.maxfile = o.maxfile * 1024; if(o.maxsize>1) o.maxsize = o.maxsize * 1024; //=== // HTML5: enforce multiple selection to be enabled, except when explicitly disabled if (o.multiple !== false) { if (o.max > 1) MultiFile.E.attr('multiple', 'multiple').prop('multiple', true); } //=== // APPLY CONFIGURATION $.extend(MultiFile, o || {}); MultiFile.STRING = $.extend({}, $.fn.MultiFile.options.STRING, MultiFile.STRING); //=== //######################################### // PRIVATE PROPERTIES/METHODS $.extend(MultiFile, { n: 0, // How many elements are currently selected? slaves: [], files: [], instanceKey: MultiFile.e.id || 'MultiFile' + String(group_count), // Instance Key? generateID: function (z) { return MultiFile.instanceKey + (z > 0 ? '_F' + String(z) : ''); }, trigger: function (event, element, MultiFile, files) { var rv, handler = MultiFile[event] || MultiFile['on'+event] ; if (handler){ files = files || MultiFile.files || FILE_LIST(this); ; $.each(files,function(i, file){ // execute function in element's context, so 'this' variable is current element rv = handler.apply(MultiFile.wrapper, [element, file.name, MultiFile, file]); }); return rv; }; } }); //=== // Setup dynamic regular expression for extension validation // - thanks to John-Paul Bader: http://smyck.de/2006/08/11/javascript-dynamic-regular-expresions/ if (String(MultiFile.accept).length > 1) { MultiFile.accept = MultiFile.accept.replace(/\W+/g, '|').replace(/^\W|\W$/g, ''); MultiFile.rxAccept = new RegExp('\\.(' + (MultiFile.accept ? MultiFile.accept : '') + ')$', 'gi'); }; //=== // Create wrapper to hold our file list MultiFile.wrapID = MultiFile.instanceKey;// + '_wrap'; // Wrapper ID? MultiFile.E.wrap('<div class="MultiFile-wrap" id="' + MultiFile.wrapID + '"></div>'); MultiFile.wrapper = $('#' + MultiFile.wrapID + ''); //=== // MultiFile MUST have a name - default: file1[], file2[], file3[] MultiFile.e.name = MultiFile.e.name || 'file' + group_count + '[]'; //=== if (!MultiFile.list) { // Create a wrapper for the list // * OPERA BUG: NO_MODIFICATION_ALLOWED_ERR ('list' is a read-only property) // this change allows us to keep the files in the order they were selected MultiFile.wrapper.append('<div class="MultiFile-list" id="' + MultiFile.wrapID + '_list"></div>'); MultiFile.list = $('#' + MultiFile.wrapID + '_list'); }; MultiFile.list = $(MultiFile.list); //=== // Bind a new element MultiFile.addSlave = function (slave, slave_count) { //if(window.console) console.log('MultiFile.addSlave',slave_count); // Keep track of how many elements have been displayed MultiFile.n++; // Add reference to master element slave.MultiFile = MultiFile; // BUG FIX: http://plugins.jquery.com/node/1495 // Clear identifying properties from clones slave.id = slave.name = ''; // Define element's ID and name (upload components need this!) //slave.id = slave.id || MultiFile.generateID(slave_count); slave.id = MultiFile.generateID(slave_count); //FIX for: http://code.google.com/p/jquery-multifile-plugin/issues/detail?id=23 //CHANGE v2.2.1 - change ID of all file elements, keep original ID in wrapper // 2008-Apr-29: New customizable naming convention (see url below) // http://groups.google.com/group/jquery-dev/browse_frm/thread/765c73e41b34f924# slave.name = String(MultiFile.namePattern /*master name*/ .replace(/\$name/gi, $(MultiFile.clone).attr('name')) /*master id */ .replace(/\$id/gi, $(MultiFile.clone).attr('id')) /*group count*/ .replace(/\$g/gi, group_count) //(group_count>0?group_count:'')) /*slave count*/ .replace(/\$i/gi, slave_count) //(slave_count>0?slave_count:'')) ); // If we've reached maximum number, disable input slave var disable_slave; if ((MultiFile.max > 0) && ((MultiFile.files.length) > (MultiFile.max))) { slave.disabled = true; disable_slave = true; }; // Remember most recent slave MultiFile.current = slave; // We'll use jQuery from now on slave = $(slave); // Clear value slave.val('').attr('value', '')[0].value = ''; // Make slave field optional to avoid validation errors slave.attr('required', false); // Stop plugin initializing on slaves slave.addClass('MultiFile-applied'); // Triggered when a file is selected slave.change(function (a, b, c) { //if(window.console) console.log('MultiFile.slave.change',slave_count); //if(window.console) console.log('MultiFile.slave.change',this.files); // Lose focus to stop IE7 firing onchange again $(this).blur(); //# NEW 2014-04-14 - accept multiple file selection, HTML5 var e = this, prevs = MultiFile.files || [], files = this.files || [{ name: this.value, size: 0, type: ((this.value || '').match(/[^\.]+$/i) || [''])[0] }], newfs = [], newfs_size = 0, total_size = MultiFile.total_size || 0/*, html5_multi_mode = this.files && $(this).attr('multiple')*/ ; // recap //console.log('START '+ prevs.length + ' files @ '+ sl(total_size) +'.', prevs); //# Retrive value of selected file from element var ERROR = []; //, v = String(this.value || ''); // make a normal array $.each(files, function (i, file) { newfs[newfs.length] = file; }); //# Trigger Event! onFileSelect MultiFile.trigger('FileSelect', this, MultiFile, newfs); //# End Event! // validate individual files $.each(files, function (i, file) { // pop local variables out of array/file object var v = file.name.replace(/^C:\\fakepath\\/gi,''), s = file.size, p = function(z){ return z .replace('$ext', String(v.match(/[^\.]+$/i) || '')) .replace('$file', v.match(/[^\/\\]+$/gi)) .replace('$size', sl(s) + ' > ' + sl(MultiFile.maxfile)) } ; // check extension if (MultiFile.accept && v && !v.match(MultiFile.rxAccept)) { ERROR[ERROR.length] = p(MultiFile.STRING.denied); MultiFile.trigger('FileInvalid', this, MultiFile, [file]); }; // Disallow duplicates $(MultiFile.wrapper).find('input[type=file]').not(e).each(function(){ // go through each file in each slave $.each(FILE_LIST(this), function (i, file) { if(file.name){ //console.log('MultiFile.debug> Duplicate?', file.name, v); var x = (file.name || '').replace(/^C:\\fakepath\\/gi,''); if ( v == x || v == x.substr(x.length - v.length)) { ERROR[ERROR.length] = p(MultiFile.STRING.duplicate); MultiFile.trigger('FileDuplicate', e, MultiFile, [file]); }; }; }); }); // limit the max size of individual files selected if (MultiFile.maxfile>0 && s>0 && s>MultiFile.maxfile) { ERROR[ERROR.length] = p(MultiFile.STRING.toobig); MultiFile.trigger('FileTooBig', this, MultiFile, [file]); }; // check extension var customError = MultiFile.trigger('FileValidate', this, MultiFile, [file]); if(customError && customError!=''){ ERROR[ERROR.length] = p(customError); }; // add up size of files selected newfs_size += file.size; }); // add up total for all files selected (existing and new) total_size += newfs_size; // put some useful information in the file array newfs.size = newfs_size; newfs.total = total_size; newfs.total_length = newfs.length + prevs.length; // limit the number of files selected if (MultiFile.max>0 && prevs.length + files.length > MultiFile.max) { ERROR[ERROR.length] = MultiFile.STRING.toomany.replace('$max', MultiFile.max); MultiFile.trigger('FileTooMany', this, MultiFile, newfs); }; // limit the max size of files selected if (MultiFile.maxsize > 0 && total_size > MultiFile.maxsize) { ERROR[ERROR.length] = MultiFile.STRING.toomuch.replace('$size', sl(total_size) + ' > ' + sl(MultiFile.maxsize)); MultiFile.trigger('FileTooMuch', this, MultiFile, newfs); }; // Create a new file input element var newEle = $(MultiFile.clone).clone(); // Copy parent attributes - Thanks to Jonas Wagner //# Let's remember which input we've generated so // we can disable the empty ones before submission // See: http://plugins.jquery.com/node/1495 newEle.addClass('MultiFile'); // Handle error if (ERROR.length > 0) { // Handle error MultiFile.error(ERROR.join('\n\n')); // 2007-06-24: BUG FIX - Thanks to Adrian Wróbel <adrian [dot] wrobel [at] gmail.com> // Ditch the trouble maker and add a fresh new element MultiFile.n--; MultiFile.addSlave(newEle[0], slave_count); slave.parent().prepend(newEle); slave.remove(); return false; } else { // if no errors have been found // remember total size MultiFile.total_size = total_size; // merge arrays files = prevs.concat(newfs); // put some useful information in the file array files.size = total_size; files.size_label = sl(total_size); // recap //console.log('NOW '+ files.length + ' files @ '+ sl(total_size) +'.', files); // remember files MultiFile.files = files; // Hide this element (NB: display:none is evil!) $(this).css({ position: 'absolute', top: '-3000px' }); // Add new element to the form slave.after(newEle); // Bind functionality MultiFile.addSlave(newEle[0], slave_count + 1); // Update list MultiFile.addToList(this, slave_count, newfs); //# Trigger Event! afterFileSelect MultiFile.trigger('afterFileSelect', this, MultiFile, newfs); //# End Event! }; // no errors detected }); // slave.change() // point to wrapper $(slave).data('MultiFile-wrap', MultiFile.wrapper); // store contorl's settings and file info in wrapper $(MultiFile.wrapper).data('MultiFile',MultiFile); // disable? if(disable_slave) $(slave).attr('disabled','disabled').prop('disabled',true); }; // MultiFile.addSlave // Bind a new element // Add a new file to the list MultiFile.addToList = function (slave, slave_count, files) { //if(window.console) console.log('MultiFile.addToList',slave_count); //# Trigger Event! onFileAppend MultiFile.trigger('FileAppend', slave, MultiFile, files); //# End Event! var names = $('<span/>'); $.each(files, function (i, file) { var v = String(file.name || '' ).replace(/[&<>'"]/g, function(c) { return '&#'+c.charCodeAt()+';'; }), S = MultiFile.STRING, n = S.label || S.file || S.name, t = S.title || S.tooltip || S.selected, p = file.type.substr(0,6) == 'image/' ? '<img class="MultiFile-preview" style="'+ MultiFile.previewCss+'"/>' : '', label = $( ( '<span class="MultiFile-label" title="' + t + '">'+ '<span class="MultiFile-title">'+ n +'</span>'+ (MultiFile.preview || $(slave).is('.with-preview') ? p : '' )+ '</span>' ) .replace(/\$(file|name)/gi, (v.match(/[^\/\\]+$/gi)||[v])[0]) .replace(/\$(ext|extension|type)/gi, (v.match(/[^\.]+$/gi)||[''])[0]) .replace(/\$(size)/gi, sl(file.size || 0)) .replace(/\$(preview)/gi, p) .replace(/\$(i)/gi, i) ); // now supports preview via locale string. // just add an <img class='MultiFile-preview'/> anywhere within the "file" string label.find('img.MultiFile-preview').each(function(){ var t = this; var oFReader = new FileReader(); oFReader.readAsDataURL(file); oFReader.onload = function (oFREvent) { t.src = oFREvent.target.result; }; }); // append file label to list if(i>0 && !!o.separator) names.append(o.separator); names.append(label); &n |
- 이전글 DOM 복사 & 삭제 1