2
### jQuery Multiple File Upload Plugin v 1.29 - 2008-06-26 ###
3
* http://www.fyneworks.com/ - diego@fyneworks.com
2
### jQuery Multiple File Upload Plugin v1.46 - 2009-05-12 ###
3
* Home: http://www.fyneworks.com/jquery/multiple-file-upload/
4
* Code: http://code.google.com/p/jquery-multifile-plugin/
4
6
* Dual licensed under the MIT and GPL licenses:
5
7
* http://www.opensource.org/licenses/mit-license.php
6
8
* http://www.gnu.org/licenses/gpl.html
8
Project: http://jquery.com/plugins/project/MultiFile/
9
Website: http://www.fyneworks.com/jquery/multiple-file-upload/
12
12
/*# AVOID COLLISIONS #*/
13
;if(jQuery) (function($){
13
;if(window.jQuery) (function($){
14
14
/*# AVOID COLLISIONS #*/
16
// extend jQuery - $.MultiFile hook
18
MultiFile: function( o /* Object */ ){
19
//return $("INPUT[@type='file'].multi").MultiFile(o);
20
return $("input:file.multi").MultiFile(o);
26
// extend $.MultiFile - default options
27
$.extend($.MultiFile, {
30
// error handling function
34
message: s.replace(/\n/gi,'<br/>'),
36
border:'none', padding:'15px', size:'12.0pt',
37
backgroundColor:'#900', color:'#fff',
38
opacity:'.8','-webkit-border-radius': '10px','-moz-border-radius': '10px'
41
window.setTimeout($.unblockUI, 2000);
47
// namePattern: $name/$id (from master element), $i (slave count), $g (group count)
49
// STRING: collection lets you show messages in different languages
52
denied:'You cannot select a $ext file.\nTry again...',
53
selected:'File selected: $file',
54
duplicate:'This file has already been selected:\n$file'
61
// extend $.MultiFile - global methods
62
$.extend($.MultiFile, {
66
* This utility makes it easy to disable all 'empty' file elements in the document before submitting a form.
67
* It marks the affected elements so they can be easily re-enabled after the form submission or validation.
69
* Returns a jQuery collection of all affected elements.
73
* @cat Plugins/Multifile
74
* @author Diego A. (http://www.fyneworks.com/)
76
* @example $.MultiFile.disableEmpty();
77
* @param String class (optional) A string specifying a class to be applied to all affected elements - Default: 'mfD'.
79
disableEmpty: function(klass){
81
$('input:file').each(function(){ if($(this).val()=='') o[o.length] = this; });
82
return $(o).each(function(){ this.disabled = true }).addClass(klass || 'mfD');
87
* This method re-enables 'empty' file elements that were disabled (and marked) with the $.MultiFile.disableEmpty method.
89
* Returns a jQuery collection of all affected elements.
93
* @cat Plugins/Multifile
94
* @author Diego A. (http://www.fyneworks.com/)
96
* @example $.MultiFile.reEnableEmpty();
97
* @param String klass (optional) A string specifying the class that was used to mark affected elements - Default: 'mfD'.
99
reEnableEmpty: function(klass){
100
klass = klass || 'mfD';
101
return $('input:file.'+klass).removeClass(klass).each(function(){ this.disabled = false });
103
autoIntercept: [ 'submit', 'ajaxSubmit', 'validate' /* array of methods to intercept */ ],
105
intercept: function(methods, context, args){
106
var method, value; args = args || [];
107
if(args.constructor.toString().indexOf("Array")<0) args = [ args ];
108
if(typeof(methods)=='function'){
109
$.MultiFile.disableEmpty();
110
value = methods.apply(context || window, args);
111
$.MultiFile.reEnableEmpty();
114
if(methods.constructor.toString().indexOf("Array")<0) methods = [methods];
115
for(var i=0;i<methods.length;i++){
116
method = methods[i]+''; // make sure that we have a STRING
117
if(method) (function(method){ // make sure that method is ISOLATED for the interception
118
$.MultiFile.intercepted[method] = $.fn[method] || function(){};
119
$.fn[method] = function(){
120
$.MultiFile.disableEmpty();
121
value = $.MultiFile.intercepted[method].apply(this, arguments);
122
$.MultiFile.reEnableEmpty();
125
})(method); // MAKE SURE THAT method IS ISOLATED for the interception
132
// extend jQuery function library
135
// Use this function to clear values of file inputs
136
// But this doesn't always work: $(element).val('').attr('value', '')[0].value = '';
137
reset: function(){ return this.each(function(){ try{ this.reset(); }catch(e){} }); },
139
// MultiFile function
140
MultiFile: function( options /* Object */ ){
142
//### http://plugins.jquery.com/node/1363
143
// utility method to integrate this plugin with others...
144
if($.MultiFile.autoIntercept){
145
$.MultiFile.intercept( $.MultiFile.autoIntercept /* array of methods to intercept */ );
146
$.MultiFile.autoIntercept = null; /* only run this once */
151
// Bind to each element in current jQuery object
152
return $(this).each(function(group_count){
153
if(this._MultiFile) return; this._MultiFile = true;
16
// plugin initialization
17
$.fn.MultiFile = function(options){
18
if(this.length==0) return this; // quick fail
21
if(typeof arguments[0]=='string'){
22
// Perform API methods on individual elements
25
return this.each(function(){
26
$.fn.MultiFile.apply($(this), args);
29
// Invoke API method handler
30
$.fn.MultiFile[arguments[0]].apply(this, $.makeArray(arguments).slice(1) || []);
35
// Initialize options for this call
36
var options = $.extend(
38
$.fn.MultiFile.options/* default options */,
39
options || {} /* just-in-time options */
42
// Empty Element Fix!!!
43
// this code will automatically intercept native form submissions
44
// and disable empty file elements
46
.not('MultiFile-intercepted')
47
.addClass('MultiFile-intercepted')
48
.submit($.fn.MultiFile.disableEmpty);
50
//### http://plugins.jquery.com/node/1363
51
// utility method to integrate this plugin with others...
52
if($.fn.MultiFile.options.autoIntercept){
53
$.fn.MultiFile.intercept( $.fn.MultiFile.options.autoIntercept /* array of methods to intercept */ );
54
$.fn.MultiFile.options.autoIntercept = null; /* only run this once */
57
// loop through each matched element
59
.not('.MultiFile-applied')
60
.addClass('MultiFile-applied')
62
//#####################################################################
63
// MAIN PLUGIN FUNCTIONALITY - START
64
//#####################################################################
155
66
// BUG 1251 FIX: http://plugins.jquery.com/project/comments/add/1251
156
67
// variable group_count would repeat itself on multiple calls to the plugin.
157
68
// this would cause a conflict with multiple elements
158
69
// changes scope of variable to global so id will be unique over n calls
159
70
window.MultiFile = (window.MultiFile || 0) + 1;
160
group_count = window.MultiFile;
71
var group_count = window.MultiFile;
162
73
// Copy parent attributes - Thanks to Jonas Wagner
163
74
// we will use this one to create new input elements
164
var MF = {e:this, E:$(this), clone:$(this).clone()};
75
var MultiFile = {e:this, E:$(this), clone:$(this).clone()};
168
79
//# USE CONFIGURATION
169
80
if(typeof options=='number') options = {max:options};
170
if(typeof options=='string') options = {accept:options};
171
81
var o = $.extend({},
82
$.fn.MultiFile.options,
174
($.meta ? MF.E.data()/*NEW metadata plugin*/ :
175
($.metadata ? MF.E.metadata()/*OLD metadata plugin*/ :
176
null/*metadata plugin not available*/)) || {}
84
($.metadata? MultiFile.E.metadata(): ($.meta?MultiFile.E.data():null)) || {}, /* metadata options */
178
87
// limit number of files that can be selected?
179
if(!(o.max>0) /*IsNull(MF.max)*/){
180
o.max = MF.E.attr('maxlength');
181
if(!(o.max>0) /*IsNull(MF.max)*/){
182
o.max = (String(MF.e.className.match(/\b(max|limit)\-([0-9]+)\b/gi) || ['']).match(/[0-9]+/gi) || [''])[0];
88
if(!(o.max>0) /*IsNull(MultiFile.max)*/){
89
o.max = MultiFile.E.attr('maxlength');
90
if(!(o.max>0) /*IsNull(MultiFile.max)*/){
91
o.max = (String(MultiFile.e.className.match(/\b(max|limit)\-([0-9]+)\b/gi) || ['']).match(/[0-9]+/gi) || [''])[0];
183
92
if(!(o.max>0)) o.max = -1;
184
93
else o.max = String(o.max).match(/[0-9]+/gi)[0];
187
96
o.max = new Number(o.max);
188
97
// limit extensions?
189
o.accept = o.accept || MF.E.attr('accept') || '';
98
o.accept = o.accept || MultiFile.E.attr('accept') || '';
191
o.accept = (MF.e.className.match(/\b(accept\-[\w\|]+)\b/gi)) || '';
100
o.accept = (MultiFile.e.className.match(/\b(accept\-[\w\|]+)\b/gi)) || '';
192
101
o.accept = new String(o.accept).replace(/^(accept|ext)\-/i,'');
197
106
// APPLY CONFIGURATION
198
$.extend(MF, o || {});
199
MF.STRING = $.extend({},$.MultiFile.options.STRING,MF.STRING);
107
$.extend(MultiFile, o || {});
108
MultiFile.STRING = $.extend({},$.fn.MultiFile.options.STRING,MultiFile.STRING);
203
112
//#########################################
204
113
// PRIVATE PROPERTIES/METHODS
114
$.extend(MultiFile, {
206
115
n: 0, // How many elements are currently selected?
207
116
slaves: [], files: [],
208
instanceKey: MF.e.id || 'MultiFile'+String(group_count), // Instance Key?
209
generateID: function(z){ return MF.instanceKey + (z>0 ?'_F'+String(z):''); },
117
instanceKey: MultiFile.e.id || 'MultiFile'+String(group_count), // Instance Key?
118
generateID: function(z){ return MultiFile.instanceKey + (z>0 ?'_F'+String(z):''); },
210
119
trigger: function(event, element){
211
var handler = MF[event], value = $(element).attr('value');
120
var handler = MultiFile[event], value = $(element).attr('value');
213
var returnValue = handler(element, value, MF);
122
var returnValue = handler(element, value, MultiFile);
214
123
if( returnValue!=null ) return returnValue;
222
131
// Setup dynamic regular expression for extension validation
223
132
// - thanks to John-Paul Bader: http://smyck.de/2006/08/11/javascript-dynamic-regular-expresions/
224
if(String(MF.accept).length>1){
225
MF.rxAccept = new RegExp('\\.('+(MF.accept?MF.accept:'')+')$','gi');
133
if(String(MultiFile.accept).length>1){
134
MultiFile.accept = MultiFile.accept.replace(/\W+/g,'|').replace(/^\W|\W$/g,'');
135
MultiFile.rxAccept = new RegExp('\\.('+(MultiFile.accept?MultiFile.accept:'')+')$','gi');
230
140
// Create wrapper to hold our file list
231
MF.wrapID = MF.instanceKey+'_wrap'; // Wrapper ID?
232
MF.E.wrap('<div id="'+MF.wrapID+'"></div>');
233
MF.wrapper = $('#'+MF.wrapID+'');
237
// MF MUST have a name - default: file1[], file2[], file3[]
238
MF.e.name = MF.e.name || 'file'+ group_count +'[]';
242
// Create a wrapper for the labels
243
// * OPERA BUG: NO_MODIFICATION_ALLOWED_ERR ('labels' is a read-only property)
244
// this changes allows us to keep the files in the order they were selected
245
MF.wrapper.append( '<span id="'+MF.wrapID+'_labels"></span>' );
246
MF.labels = $('#'+MF.wrapID+'_labels');
141
MultiFile.wrapID = MultiFile.instanceKey+'_wrap'; // Wrapper ID?
142
MultiFile.E.wrap('<div class="MultiFile-wrap" id="'+MultiFile.wrapID+'"></div>');
143
MultiFile.wrapper = $('#'+MultiFile.wrapID+'');
147
// MultiFile MUST have a name - default: file1[], file2[], file3[]
148
MultiFile.e.name = MultiFile.e.name || 'file'+ group_count +'[]';
153
// Create a wrapper for the list
154
// * OPERA BUG: NO_MODIFICATION_ALLOWED_ERR ('list' is a read-only property)
155
// this change allows us to keep the files in the order they were selected
156
MultiFile.wrapper.append( '<div class="MultiFile-list" id="'+MultiFile.wrapID+'_list"></div>' );
157
MultiFile.list = $('#'+MultiFile.wrapID+'_list');
159
MultiFile.list = $(MultiFile.list);
250
163
// Bind a new element
251
MF.addSlave = function( slave, slave_count ){
164
MultiFile.addSlave = function( slave, slave_count ){
165
//if(window.console) console.log('MultiFile.addSlave',slave_count);
252
167
// Keep track of how many elements have been displayed
254
169
// Add reference to master element
257
slave.i = slave_count;
259
// BUG FIX: http://plugins.jquery.com/node/1495
260
// Clear identifying properties from clones
261
if(slave.i>0) slave.id = slave.name = null;
170
slave.MultiFile = MultiFile;
172
// BUG FIX: http://plugins.jquery.com/node/1495
173
// Clear identifying properties from clones
174
if(slave_count>0) slave.id = slave.name = '';
263
176
// Define element's ID and name (upload components need this!)
264
slave.id = slave.id || MF.generateID(slave.i);
266
//slave.name = (slave.name || MF.E.attr('name') || 'file');// + (slave.i>0?slave.i:''); // same name as master element
177
//slave.id = slave.id || MultiFile.generateID(slave_count);
178
if(slave_count>0) slave.id = MultiFile.generateID(slave_count);
179
//FIX for: http://code.google.com/p/jquery-multifile-plugin/issues/detail?id=23
267
181
// 2008-Apr-29: New customizable naming convention (see url below)
268
182
// http://groups.google.com/group/jquery-dev/browse_frm/thread/765c73e41b34f924#
269
slave.name = String(MF.namePattern
270
/*master name*/.replace(/\$name/gi,MF.E.attr('name'))
271
/*master id */.replace(/\$id/gi, MF.E.attr('id'))
272
/*group count*/.replace(/\$g/gi, (group_count>0?group_count:''))
273
/*slave count*/.replace(/\$i/gi, (slave_count>0?slave_count:''))
183
slave.name = String(MultiFile.namePattern
184
/*master name*/.replace(/\$name/gi,$(MultiFile.clone).attr('name'))
185
/*master id */.replace(/\$id/gi, $(MultiFile.clone).attr('id'))
186
/*group count*/.replace(/\$g/gi, group_count)//(group_count>0?group_count:''))
187
/*slave count*/.replace(/\$i/gi, slave_count)//(slave_count>0?slave_count:''))
277
$(slave).val('').attr('value','')[0].value = '';
279
190
// If we've reached maximum number, disable input slave
280
if( (MF.max > 0) && ((MF.n-1) > (MF.max)) )//{ // MF.n Starts at 1, so subtract 1 to find true count
191
if( (MultiFile.max > 0) && ((MultiFile.n-1) > (MultiFile.max)) )//{ // MultiFile.n Starts at 1, so subtract 1 to find true count
281
192
slave.disabled = true;
284
195
// Remember most recent slave
285
MF.current = MF.slaves[slave.i] = slave;
287
// now let's use jQuery
196
MultiFile.current = MultiFile.slaves[slave_count] = slave;
198
// We'll use jQuery from now on
202
slave.val('').attr('value','')[0].value = '';
204
// Stop plugin initializing on slaves
205
slave.addClass('MultiFile-applied');
290
207
// Triggered when a file is selected
291
$(slave).change(function(){
208
slave.change(function(){
209
//if(window.console) console.log('MultiFile.slave.change',slave_count);
293
211
// Lose focus to stop IE7 firing onchange again
296
214
//# Trigger Event! onFileSelect
297
if(!MF.trigger('onFileSelect', this, MF)) return false;
215
if(!MultiFile.trigger('onFileSelect', this, MultiFile)) return false;
300
218
//# Retrive value of selected file from element
301
219
var ERROR = '', v = String(this.value || ''/*.attr('value)*/);
303
221
// check extension
306
if(!v.match(MF.rxAccept)){
307
ERROR = MF.STRING.denied.replace('$ext', String(v.match(/\.\w{1,4}$/gi)));
222
if(MultiFile.accept && v && !v.match(MultiFile.rxAccept))//{
223
ERROR = MultiFile.STRING.denied.replace('$ext', String(v.match(/\.\w{1,4}$/gi)));
312
227
// Disallow duplicates
313
for(var f=0;f<MF.slaves.length;f++){
314
if(MF.slaves[f]!=this){
315
if(MF.slaves[f].value==v){
316
ERROR = MF.STRING.duplicate.replace('$file', v.match(/[^\/\\]+$/gi));
228
for(var f in MultiFile.slaves)//{
229
if(MultiFile.slaves[f] && MultiFile.slaves[f]!=this)//{
230
//console.log(MultiFile.slaves[f],MultiFile.slaves[f].value);
231
if(MultiFile.slaves[f].value==v)//{
232
ERROR = MultiFile.STRING.duplicate.replace('$file', v.match(/[^\/\\]+$/gi));
321
237
// Create a new file input element
322
//var newEle = $('<input name="'+(MF.E.attr('name') || '')+'" type="file"/>');
323
var newEle = $(MF.clone).clone();// Copy parent attributes - Thanks to Jonas Wagner
238
var newEle = $(MultiFile.clone).clone();// Copy parent attributes - Thanks to Jonas Wagner
324
239
//# Let's remember which input we've generated so
325
240
// we can disable the empty ones before submission
326
241
// See: http://plugins.jquery.com/node/1495
327
242
newEle.addClass('MultiFile');
334
// Clear element value (DOES NOT WORK in some browsers)
335
//slave.reset().val('').attr('value', '')[0].value = '';
337
// 2007-06-24: BUG FIX - Thanks to Adrian Wróbel <adrian [dot] wrobel [at] gmail.com>
247
MultiFile.error(ERROR);
249
// 2007-06-24: BUG FIX - Thanks to Adrian Wr�bel <adrian [dot] wrobel [at] gmail.com>
338
250
// Ditch the trouble maker and add a fresh new element
340
MF.addSlave(newEle[0], this.i);
252
MultiFile.addSlave(newEle[0], slave_count);
341
253
slave.parent().prepend(newEle);
346
258
// Hide this element (NB: display:none is evil!)
347
259
$(this).css({ position:'absolute', top: '-3000px' });
349
261
// Add new element to the form
350
MF.labels.before(newEle);//.append(newEle);
353
MF.addToList( this );
265
MultiFile.addToList( this, slave_count );
355
267
// Bind functionality
356
MF.addSlave( newEle[0], this.i+1 );
268
MultiFile.addSlave( newEle[0], slave_count+1 );
358
270
//# Trigger Event! afterFileSelect
359
if(!MF.trigger('afterFileSelect', this, MF)) return false;
271
if(!MultiFile.trigger('afterFileSelect', this, MultiFile)) return false;
362
274
}); // slave.change()
276
// Save control to element
277
$(slave).data('MultiFile', MultiFile);
279
};// MultiFile.addSlave
365
280
// Bind a new element
369
284
// Add a new file to the list
370
MF.addToList = function( slave ){
285
MultiFile.addToList = function( slave, slave_count ){
286
//if(window.console) console.log('MultiFile.addToList',slave_count);
372
288
//# Trigger Event! onFileAppend
373
if(!MF.trigger('onFileAppend', slave, MF)) return false;
289
if(!MultiFile.trigger('onFileAppend', slave, MultiFile)) return false;
376
292
// Create label elements
378
r = $('<div></div>'),
294
r = $('<div class="MultiFile-label"></div>'),
379
295
v = String(slave.value || ''/*.attr('value)*/),
380
a = $('<span class="file" title="'+MF.STRING.selected.replace('$file', v)+'">'+v.match(/[^\/\\]+$/gi)[0]+'</span>'),
381
b = $('<a href="#'+MF.wrapID+'">'+MF.STRING.remove+'</a>');
296
a = $('<span class="MultiFile-title" title="'+MultiFile.STRING.selected.replace('$file', v)+'">'+MultiFile.STRING.file.replace('$file', v.match(/[^\/\\]+$/gi)[0])+'</span>'),
297
b = $('<a class="MultiFile-remove" href="#'+MultiFile.wrapID+'">'+MultiFile.STRING.remove+'</a>');
385
r.append('[', b, '] ', a)//.prepend(slave.i+': ')
300
MultiFile.list.append(
390
307
//# Trigger Event! onFileRemove
391
if(!MF.trigger('onFileRemove', slave, MF)) return false;
308
if(!MultiFile.trigger('onFileRemove', slave, MultiFile)) return false;
395
MF.current.disabled = false;
312
MultiFile.current.disabled = false;
397
314
// Remove element, remove label, point to current
399
$(MF.current).remove();
405
$(this).parent().remove();
315
MultiFile.slaves[slave_count] = null;
317
$(this).parent().remove();
407
319
// Show most current element again (move into view) and clear selection
408
$(MF.current).css({ position:'', top: '' }).reset().val('').attr('value', '')[0].value = '';
320
$(MultiFile.current).css({ position:'', top: '' });
321
$(MultiFile.current).reset().val('').attr('value', '')[0].value = '';
410
323
//# Trigger Event! afterFileRemove
411
if(!MF.trigger('afterFileRemove', slave, MF)) return false;
324
if(!MultiFile.trigger('afterFileRemove', slave, MultiFile)) return false;
418
330
//# Trigger Event! afterFileAppend
419
if(!MF.trigger('afterFileAppend', slave, MF)) return false;
331
if(!MultiFile.trigger('afterFileAppend', slave, MultiFile)) return false;
334
}; // MultiFile.addToList
423
335
// Add element to selected files list
427
339
// Bind functionality to the first element
428
if(!MF.MF) MF.addSlave(MF.e, 0);
340
if(!MultiFile.MultiFile) MultiFile.addSlave(MultiFile.e, 0);
430
342
// Increment control count
431
//MF.I++; // using window.MultiFile
438
// MultiFile function
441
// extend jQuery function library
446
### Default implementation ###
447
The plugin will attach itself to file inputs
448
with the class 'multi' when the page loads
450
$(function(){ $.MultiFile() });
343
//MultiFile.I++; // using window.MultiFile
346
// Save control to element
347
MultiFile.E.data('MultiFile', MultiFile);
350
//#####################################################################
351
// MAIN PLUGIN FUNCTIONALITY - END
352
//#####################################################################
356
/*--------------------------------------------------------*/
359
### Core functionality and API ###
361
$.extend($.fn.MultiFile, {
363
* This method removes all selected files
365
* Returns a jQuery collection of all affected elements.
369
* @cat Plugins/MultiFile
370
* @author Diego A. (http://www.fyneworks.com/)
372
* @example $.fn.MultiFile.reset();
375
var settings = $(this).data('MultiFile');
376
//if(settings) settings.wrapper.find('a.MultiFile-remove').click();
377
if(settings) settings.list.find('a.MultiFile-remove').click();
383
* This utility makes it easy to disable all 'empty' file elements in the document before submitting a form.
384
* It marks the affected elements so they can be easily re-enabled after the form submission or validation.
386
* Returns a jQuery collection of all affected elements.
390
* @cat Plugins/MultiFile
391
* @author Diego A. (http://www.fyneworks.com/)
393
* @example $.fn.MultiFile.disableEmpty();
394
* @param String class (optional) A string specifying a class to be applied to all affected elements - Default: 'mfD'.
396
disableEmpty: function(klass){ klass = (typeof(klass)=='string'?klass:'')||'mfD';
398
$('input:file.MultiFile').each(function(){ if($(this).val()=='') o[o.length] = this; });
399
return $(o).each(function(){ this.disabled = true }).addClass(klass);
404
* This method re-enables 'empty' file elements that were disabled (and marked) with the $.fn.MultiFile.disableEmpty method.
406
* Returns a jQuery collection of all affected elements.
408
* @name reEnableEmpty
410
* @cat Plugins/MultiFile
411
* @author Diego A. (http://www.fyneworks.com/)
413
* @example $.fn.MultiFile.reEnableEmpty();
414
* @param String klass (optional) A string specifying the class that was used to mark affected elements - Default: 'mfD'.
416
reEnableEmpty: function(klass){ klass = (typeof(klass)=='string'?klass:'')||'mfD';
417
return $('input:file.'+klass).removeClass(klass).each(function(){ this.disabled = false });
422
* This method will intercept other jQuery plugins and disable empty file input elements prior to form submission
426
* @cat Plugins/MultiFile
427
* @author Diego A. (http://www.fyneworks.com/)
429
* @example $.fn.MultiFile.intercept();
430
* @param Array methods (optional) Array of method names to be intercepted
433
intercept: function(methods, context, args){
434
var method, value; args = args || [];
435
if(args.constructor.toString().indexOf("Array")<0) args = [ args ];
436
if(typeof(methods)=='function'){
437
$.fn.MultiFile.disableEmpty();
438
value = methods.apply(context || window, args);
439
//SEE-http://code.google.com/p/jquery-multifile-plugin/issues/detail?id=27
440
setTimeout(function(){ $.fn.MultiFile.reEnableEmpty() },1000);
443
if(methods.constructor.toString().indexOf("Array")<0) methods = [methods];
444
for(var i=0;i<methods.length;i++){
445
method = methods[i]+''; // make sure that we have a STRING
446
if(method) (function(method){ // make sure that method is ISOLATED for the interception
447
$.fn.MultiFile.intercepted[method] = $.fn[method] || function(){};
448
$.fn[method] = function(){
449
$.fn.MultiFile.disableEmpty();
450
value = $.fn.MultiFile.intercepted[method].apply(this, arguments);
451
//SEE-http://code.google.com/p/jquery-multifile-plugin/issues/detail?id=27
452
setTimeout(function(){ $.fn.MultiFile.reEnableEmpty() },1000);
455
})(method); // MAKE SURE THAT method IS ISOLATED for the interception
460
/*--------------------------------------------------------*/
463
### Default Settings ###
464
eg.: You can override default control like this:
465
$.fn.MultiFile.options.accept = 'gif|jpg';
467
$.fn.MultiFile.options = { //$.extend($.fn.MultiFile, { options: {
468
accept: '', // accepted file extensions
469
max: -1, // maximum number of selectable files
471
// name to use for newly created elements
472
namePattern: '$name', // same name by default (which creates an array)
474
// STRING: collection lets you show messages in different languages
477
denied:'You cannot select a $ext file.\nTry again...',
479
selected:'File selected: $file',
480
duplicate:'This file has already been selected:\n$file'
483
// name of methods that should be automcatically intercepted so the plugin can disable
484
// extra file elements that are empty before execution and automatically re-enable them afterwards
485
autoIntercept: [ 'submit', 'ajaxSubmit', 'ajaxForm', 'validate' /* array of methods to intercept */ ],
487
// error handling function
490
ERROR! blockUI is not currently working in IE
493
message: s.replace(/\n/gi,'<br/>'),
495
border:'none', padding:'15px', size:'12.0pt',
496
backgroundColor:'#900', color:'#fff',
497
opacity:'.8','-webkit-border-radius': '10px','-moz-border-radius': '10px'
500
window.setTimeout($.unblockUI, 2000);
502
else//{// save a byte!
509
/*--------------------------------------------------------*/
512
### Additional Methods ###
513
Required functionality outside the plugin's scope
516
// Native input reset method - because this alone doesn't always work: $(element).val('').attr('value', '')[0].value = '';
517
$.fn.reset = function(){ return this.each(function(){ try{ this.reset(); }catch(e){} }); };
519
/*--------------------------------------------------------*/
522
### Default implementation ###
523
The plugin will attach itself to file inputs
524
with the class 'multi' when the page loads
527
//$("input:file.multi").MultiFile();
528
$("input[type=file].multi").MultiFile();
454
533
/*# AVOID COLLISIONS #*/
456
535
/*# AVOID COLLISIONS #*/