root/public/javascripts/MultiUpload.js

Revision 1, 6.5 kB (checked in by falcon, 16 years ago)

Version one -> initial work from the laptop.

Line 
1// Multiple file upload element (Mootools 1.1 version) by Stickman http://the-stickman.com
2// Licence: You may use this script as you wish without limitation, however I would appreciate it if you left at least the credit and site link above in place. I accept no liability for any problems or damage encountered as a result of using this script.
3// Modifications by: SilverTab (http://www.silverscripting.com) to allow compatibility with Rails + file_column
4
5var MultiUpload = new Class(
6{
7 
8    new MultiUpload( $( â€˜main_form‘ ).user_picture, 3, â€˜[{id}][image]‘, true, true, â€˜[{id}][image_temp]‘ );
9
10        initialize:function( input_element, max, name_suffix_template, show_filename_only, remove_empty_element, hidden_suffix_template ){
11
12                // Sanity check -- make sure it's  file input element
13                if( !( input_element.tagName == 'INPUT' && input_element.type == 'file' ) ){
14                        alert( 'Error: not a file input element' );
15                        return;
16                }
17
18                // List of elements
19                this.elements = [];
20
21               
22                // Lookup for row ID => array ID
23                this.uid_lookup = {};
24                // Current row ID
25                this.uid = 0;
26
27                // Maximum number of selected files (default = 0, ie. no limit)
28                // This is optional
29                if( $defined( max ) ){
30                        this.max = max;
31                } else {
32                        this.max = 0;
33                }
34
35                // Template for adding id to file name
36                // This is optional
37                if( $defined( name_suffix_template ) ){
38                        this.name_suffix_template = name_suffix_template;
39                } else {
40                        this.name_suffix_template= '_{id}';
41                }
42               
43                if( $defined( hidden_suffix_template ) ){
44                        this.hidden_suffix_template = hidden_suffix_template;
45                } else {
46                        this.hidden_suffix_template= '_{id}_temp';
47                }
48
49                // Show only filename (i.e. remove path)
50                // This is optional
51                if( $defined( show_filename_only ) ){
52                        this.show_filename_only = show_filename_only;
53                } else {
54                        this.show_filename_only = false;
55                }
56               
57                // Remove empty element before submitting form
58                // This is optional
59                if( $defined( remove_empty_element ) ){
60                        this.remove_empty_element = remove_empty_element;
61                } else {
62                        this.remove_empty_element = false;
63                }
64
65                // Add element methods
66                $( input_element );
67
68                // Base name for input elements
69                this.name = input_element.name;
70                var input_hidden = new Element(
71                        'input',
72                        {
73                                'type':'hidden'
74                        }
75                );
76                // Set up element for multi-upload functionality
77                this.initializeElement( input_element, input_hidden );
78                input_hidden.injectAfter(input_element);
79
80               
81                // Files list
82                var container = new Element(
83                        'div',
84                        {
85                                'class':'multiupload'
86                        }
87                );
88                this.list = new Element(
89                        'div',
90                        {
91                                'class':'list'
92                        }
93                );
94                container.injectAfter( input_element );
95                container.adopt( input_element );
96                container.adopt( this.list );
97               
98                // Causes the 'extra' (empty) element not to be submitted
99                if( this.remove_empty_element){
100                        input_element.form.addEvent(
101                                'submit',function(){
102                                        this.elements.getLast().element.disabled = true;
103                                        this.elements.getLast().hiddenelement.disabled = true;
104                                }.bind( this )
105                        );
106                }
107        },
108
109       
110        /**
111         * Called when a file is selected
112         */
113        addRow:function(){
114                if( this.max == 0 || this.elements.length <= this.max ){
115               
116                        current_element = this.elements.getLast();
117
118                        // Create new row in files list
119                        var name = current_element.element.value;
120                        // Extract file name?
121                        if( this.show_filename_only ){
122                                if( name.contains( '\\' ) ){
123                                        name = name.substring( name.lastIndexOf( '\\' ) + 1 );
124                                }
125                                if( name.contains( '//' ) ){
126                                        name = name.substring( name.lastIndexOf( '//' ) + 1 );
127                                }
128                        }
129                        var item = new Element(
130                                'span'
131                        ).setText( name );
132                        var delete_button = new Element(
133                                'img',
134                                {
135                                        'src':'/images/cross_small.gif',
136                                        'alt':'Delete',
137                                        'title':'Delete',
138                                        'events':{
139                                                'click':function( uid ){
140                                                        this.deleteRow( uid );
141                                                }.pass( current_element.uid, this )
142                                        }
143                                }
144                        );
145                        var row_element = new Element(
146                                'div',
147                                {
148                                        'class':'item'
149                                }
150                        ).adopt( delete_button ).adopt( item );
151                        this.list.adopt( row_element );
152                        current_element.row = row_element;
153                       
154                        // Create new file input element
155                        var new_input = new Element
156                        (
157                                'input',
158                                {
159                                        'type':'file',
160                                        'disabled':( this.elements.length == this.max )?true:false
161                                }
162                        );
163                       
164                        var new_hidden_input = new Element
165                        (
166                                'input',
167                                {
168                                        'type':'hidden'
169                                }
170                        )
171                       
172                        // Apply multi-upload functionality to new element
173                        this.initializeElement(new_input, new_hidden_input);
174                       
175                        // Add new element to page
176                        current_element.element.style.position = 'absolute';
177                        current_element.element.style.left = '-1000px';
178                        new_input.injectAfter( current_element.element );
179                        new_hidden_input.injectAfter(current_element.element);
180                } else {
181                        alert( 'You may not upload more than ' + this.max + ' files'  );
182                }
183               
184        },
185
186        /**
187         * Called when the delete button of a row is clicked
188         */
189        deleteRow:function( uid ){
190       
191                // Confirm before delete
192                deleted_row = this.elements[ this.uid_lookup[ uid ] ];
193                if( confirm( 'Are you sure you want to remove the item\r\n' +  deleted_row.element.value + '\r\nfrom the upload queue?' ) ){
194                        this.elements.getLast().element.disabled = false;
195                        deleted_row.element.remove();
196                        deleted_row.row.remove();
197                        deleted_row.hiddenelement.remove();
198                        // Get rid of this row in the elements list
199                        delete(this.elements[  this.uid_lookup[ uid ] ]);
200
201                        // Rewrite IDs
202                        var new_elements=[];
203                        this.uid_lookup = {};
204                        for( var i = 0; i < this.elements.length; i++ ){
205                                if( $defined( this.elements[ i ] ) ){
206                                        this.elements[ i ].element.name = this.name + this.name_suffix_template.replace( /\{id\}/, new_elements.length );
207                                        this.elements[ i ].hiddenelement.name = this.name + this.hidden_suffix_template.replace(/\{id\}/, new_elements.length)
208                                        this.uid_lookup[ this.elements[ i ].uid ] = new_elements.length;
209                                        new_elements.push( this.elements[ i ] );
210
211                                }
212                               
213                       
214                        }
215                        this.elements = new_elements;
216
217                }
218        },
219
220        /**
221         * Apply multi-upload functionality to an element
222         *
223         * @param               HTTPFileInputElement            element         The element
224         */
225        initializeElement:function( element, hiddenelement ){
226
227                // What happens when a file is selected
228                element.addEvent(
229                        'change',
230                        function(){
231                                this.addRow()
232                        }.bind( this )
233                );
234                // Set the name
235                element.name = this.name + this.name_suffix_template.replace( /\{id\}/, this.elements.length );
236                hiddenelement.name = this.name + this.hidden_suffix_template.replace(/\{id\}/, this.elements.length)
237                // Store it for later
238               
239                this.uid_lookup[ this.uid ] = this.elements.length;
240                this.elements.push( { 'uid':this.uid, 'element':element, 'hiddenelement':hiddenelement } );
241                this.uid++;
242       
243        }
244}
245);
Note: See TracBrowser for help on using the browser.