root/public/javascripts/multi_selector.js @ 1

Revision 1, 6.8 kB (checked in by falcon, 17 years ago)

Version one -> initial work from the laptop.

RevLine 
[1]1/**
2 * Convert a single file-input element into a 'multiple' input list
3 *
4 * Usage:
5 *
6 *   1. Create a file input element (no name)
7 *      eg. <input type="file" id="first_file_element">
8 *
9 *   2. Create a DIV for the output to be written to
10 *      eg. <div id="files_list"></div>
11 *
12 *   3. Instantiate a MultiSelector object, arguments:
13 *      Pass in the Object of the div of the output list
14 *      Pass an (optional) maximum number of files
15 *      Pass the element_id, this is for using this script multiple times in a page
16 *      Pass the allowed file extensions javascript array (optional)
17 *
18 *      You can edit this two more options:
19 *      // Should we display the filename only (without the path)
20 *      this.filename_only = true;
21 *      // Should there be a confirmation for deletion of the upload queue?
22 *      var ask_for_deletion_confirmation = true;
23 *
24 *   4. Add the first element
25 *      eg. multi_selector.addElement( document.getElementById( 'first_file_element' ) );
26 *
27 *   5. That's it.
28 *
29 *   For example:
30       <input id="collection_preview" type="file" name="collection_preview_1" />
31       <div id="collection_preview_list"></div>
32       <script type="text/javascript">
33         var multi_selector = new MultiSelector( document.getElementById('collection_preview_list'), 0, 'collection_preview', new Array('jpg', 'gif', 'png') );
34         multi_selector.addElement( document.getElementById( 'collection_preview' ) );
35       </script>
36 *
37 *   You might (will) want to play around with the addListRow() method to make the output prettier.
38 *
39 * Licence:
40 *   Use this however/wherever you like, just don't blame me if it breaks anything.
41 *
42 * Credit:
43 *   If you're nice, you'll leave this bit:
44 *
45 *   Class by Stickman -- http://www.the-stickman.com
46 *     pimped by Johannes Leers -- http://www.gauda.de
47 */
48function MultiSelector( list_target, max, element_id, allowed_file_extensions ){
49
50  // Where to write the list
51  this.list_target = list_target;
52  // How many elements?
53  this.count = 0;
54  // How many elements?
55  this.id = 0;
56  // Is there a maximum?
57  if( max ){
58    this.max = max;
59  } else {
60    this.max = -1;
61  };
62        this.element_id = element_id;
63
64        // Should we display the filename only (without the path)
65        this.filename_only = true;
66        // Should there be a confirmation for deletion of the upload queue?
67        var ask_for_deletion_confirmation = true;
68
69  /**
70   * Add a new file input element
71   */
72  this.addElement = function( element ){
73
74    // Make sure it's a file input element
75    if( element.tagName == 'INPUT' && element.type == 'file' ){
76
77      // Element name -- what number am I?
78      element.name = this.element_id + '[' + this.id++ + ']';
79
80      // Add reference to this object
81      element.multi_selector = this;
82
83      // What to do when a file is selected
84      element.onchange = function(){
85                                // Check if file extension is valid
86                                if(allowed_file_extensions){
87                                  var file_extension = this.value.substr(this.value.lastIndexOf(".")+1, this.value.length).toLowerCase();
88                                  var file_extension_valid = false;
89                                  for(var i=0; i < allowed_file_extensions.length; i++) {
90                                    if(allowed_file_extensions[i] == file_extension) {
91                                      file_extension_valid = true;
92                                    }
93                                  }
94                                  // Abort if file extension is not valid
95                                  if(!file_extension_valid){
96                                    alert('This file extension is not valid!');
97                                    this.value = '';
98                                    return;
99                                  }
100                                }
101
102        // New file input
103        var new_element = document.createElement( 'input' );
104        new_element.type = 'file';
105
106        // Add new element
107        this.parentNode.insertBefore( new_element, this );
108
109        // Apply 'update' to element
110        this.multi_selector.addElement( new_element );
111
112        // Update list
113        this.multi_selector.addListRow( this );
114
115        // Hide this: we can't use display:none because Safari doesn't like it
116        this.style.position = 'absolute';
117        this.style.left = '-1000px';
118
119      };
120      // If we've reached maximum number, disable input element
121      if( this.max != -1 && this.count >= this.max ){
122        element.disabled = true;
123      };
124
125      // File element counter
126      this.count++;
127      // Most recent element
128      this.current_element = element;
129
130    } else {
131      // This can only be applied to file input elements!
132      alert( 'Error: not a file input element' );
133    };
134
135  };
136
137  /**
138   * Add a new row to the list of files
139   */
140  this.addListRow = function( element ){
141
142    // Row div
143    var new_row = document.createElement( 'div' );
144
145    // Delete image
146    var new_row_image = document.createElement( 'img' );
147    new_row_image.src = '/images/icon-delete.gif';
148    new_row_image.alt = 'Delete this file from upload queue!';
149    new_row_image.title = 'Delete this file from upload queue!';
150
151    // References
152    new_row.element = element;
153
154    // Delete function
155    new_row_image.onclick = function(){
156                  if(!ask_for_deletion_confirmation || confirm('Are you sure you want to delete this file from upload queue?')==true){
157
158                    // Remove element from form
159                    this.parentNode.element.parentNode.removeChild( this.parentNode.element );
160
161                    // Remove this row from the list
162                    this.parentNode.parentNode.removeChild( this.parentNode );
163
164                    // Decrement counter
165                    this.parentNode.element.multi_selector.count--;
166
167                    // Re-enable input element (if it's disabled)
168                    this.parentNode.element.multi_selector.current_element.disabled = false;
169
170                    // Appease Safari
171                    //    without it Safari wants to reload the browser window
172                    //    which nixes your already queued uploads
173                    return false;
174                  }
175
176    };
177
178    // Add image
179    new_row.appendChild( new_row_image );
180
181                // Edit output if filename only
182                if(this.filename_only){
183                  var filename = element.value.match(/(.*)[\/\\]([^\/\\]+\.\w+)$/);
184                  filename = (filename == null)? element.value : filename[2];
185                }else{
186                  var filename = element.value;
187                }
188
189    // Set row value
190    new_row.appendChild( document.createTextNode(filename) );
191
192    // Add it to the list
193    this.list_target.appendChild( new_row );
194
195  };
196
197};
198
Note: See TracBrowser for help on using the browser.