/
multifile.js
executable file
·189 lines (150 loc) · 4.99 KB
/
multifile.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/**
* Convert a single file-input element into a 'multiple' input list
*
* Modified 2006-11-06 by Silverstripe Ltd.
*
* Usage:
*
* 1. Create a file input element (no name)
* eg. <input type="file" id="first_file_element">
*
* 2. Create a DIV for the output to be written to
* eg. <div id="files_list"></div>
*
* 3. Instantiate a MultiSelector object, passing in the DIV and an (optional) maximum number of files
* eg. var multi_selector = new MultiSelector( document.getElementById( 'files_list' ), 3 );
*
* 4. Add the first element
* eg. multi_selector.addElement( document.getElementById( 'first_file_element' ) );
*
* 5. That's it.
*
* You might (will) want to play around with the addListRow() method to make the output prettier.
*
* You might also want to change the line
* element.name = 'file_' + this.count;
* ...to a naming convention that makes more sense to you.
*
* Licence:
* Use this however/wherever you like, just don't blame me if it breaks anything.
*
* Credit:
* If you're nice, you'll leave this bit:
*
* Class by Stickman -- http://www.the-stickman.com
* with thanks to:
* [for Safari fixes]
* Luis Torrefranca -- http://www.law.pitt.edu
* and
* Shawn Parker & John Pennypacker -- http://www.fuzzycoconut.com
* [for duplicate name bug]
* 'neal'
*/
// Modified by: Silverstripe Ltd. (changed naming of file-input-elements)
function MultiSelector( list_target, max, upload_button ){
this.upload_button = upload_button;
this.upload_button.setAttribute("disabled", "disabled");
// Where to write the list
this.list_target = list_target;
// How many elements?
this.count = -1;
// How many elements?
this.id = 0;
// Is there a maximum?
if( max ){
this.max = max;
} else {
this.max = -1;
};
/**
* Add a new file input element
*/
this.addElement = function( element ){
// Make sure it's a file input element
if( element.tagName == 'INPUT' && element.type == 'file' ){
// Element name -- what number am I?
// Modified by: Silverstripe Ltd. (changed naming of file-input-elements)
element.name = 'Files[' + this.id++ + ']'
// If we've reached maximum number, disable input element
if( this.max != -1 && this.count >= this.max ){
element.disabled = true;
};
// File element counter
this.count++;
// Add reference to this object
element.__scope = this;
element.multi_selector = this;
// What to do when a file is selected
element.onchange = function(){
// New file input
var new_element = document.createElement( 'input' );
new_element.type = 'file';
// Add new element
this.parentNode.insertBefore( new_element, this );
// Apply 'update' to element
this.multi_selector.addElement( new_element );
// Update list
this.multi_selector.addListRow( this );
// Hide this: we can't use display:none because Safari doesn't like it
this.style.position = 'absolute';
this.style.left = '-1000px';
element.__scope.toggleUploadButton();
};
// Most recent element
this.current_element = element;
} else {
// This can only be applied to file input elements!
alert( 'Error: not a file input element' );
};
};
this.toggleUploadButton = function() {
if(this.count > 0) {
this.upload_button.removeAttribute("disabled");
} else {
this.upload_button.setAttribute("disabled", "disabled");
}
}
/**
* Add a new row to the list of files
*/
this.addListRow = function( element ){
// Modified 2006-11-06 by Silverstripe Ltd.
var filenameMatches = element.value.match(/([^\/\\]+)$/);
var filename = filenameMatches[1];
// Row div
var new_row = document.createElement('div');
// Delete button
var new_row_button = document.createElement('input');
new_row_button.type = 'button';
new_row_button.value = 'Delete';
new_row_button.setAttribute('class', 'delete');
// References
new_row.element = element;
element.__scope = this,
// Delete function
new_row_button.onclick= function(){
// Remove element from form
this.parentNode.element.parentNode.removeChild( this.parentNode.element );
// Remove this row from the list
this.parentNode.parentNode.removeChild( this.parentNode );
// Decrement counter
this.parentNode.element.multi_selector.count--;
// Re-enable input element (if it's disabled)
this.parentNode.element.multi_selector.current_element.disabled = false;
element.__scope.toggleUploadButton();
// Appease Safari
// without it Safari wants to reload the browser window
// which nixes your already queued uploads
return false;
};
// Set row value
// Modified 2006-11-06 by Silverstripe Ltd.
new_row.innerHTML = filename;
// Add button
new_row.appendChild( new_row_button );
// Add it to the list
this.list_target.appendChild( new_row );
// Modified 2006-11-06 by Silverstripe Ltd.
if(typeof(window.ontabschanged) != 'undefined') window.ontabschanged();
};
};