//= require dropzone //= require voltron Dropzone.autoDiscover = false; Voltron.addModule('Upload', function(){ var _dz = null, _form = null; var Upload = function(element){ return { initialize: function(){ _form = this.getInput().closest('form'); this.createMarkup().createDropzone(); }, getInput: function(){ return $(element); }, getForm: function(){ return _form; }, isMultiple: function(){ return this.getInput().prop('multiple'); }, getModel: function(){ return this.getInput().attr('name').match(/^[A-Z_0-9]+/i)[0]; }, getMethod: function(){ return this.getInput().attr('name').match(/^[A-Z_0-9]+\[([A-Z_0-9]+)\]/i)[1]; }, getParamName: function(name){ return this.getModel() + '[' + name + '_' + this.getMethod() + ']' + (this.isMultiple() ? '[]' : ''); }, getDropzone: function(){ return _dz; }, getRemovals: function(){ return this.getInput().data('upload-remove') || []; }, getFiles: function(){ return this.getInput().data('upload-files') || []; }, getOptions: function(){ return this.getInput().data('upload-options'); }, addHiddenInputs: function(){ var removes = this.getRemovals(); for(var i=0; i -1){ cache.splice(index, 1); if(this.isMultiple()){ this.getCacheInput().val(JSON.stringify(cache)); }else{ this.getCacheInput().val(''); } } // Add the removal input field with the given id this.getForm().prepend($('', { type: 'hidden', class: 'input-' + id.split('/')[0], name: this.getParamName('remove'), value: id })); }, addCache: function(id){ if(!/^(-)?[\d]+\-[\d]+(\-[\d]{4})?\-[\d]{4}/.test(id)) return; if(this.isMultiple()){ var cache = this.getCache(); cache.push(id); this.getCacheInput().val(JSON.stringify(cache.uniq())); }else{ this.getCacheInput().val(id); } }, getCache: function(){ try { if(this.isMultiple()){ return $.parseJSON(this.getCacheInput().val()) || []; }else{ return [this.getCacheInput().val()]; } }catch(e){ return []; } }, getCacheIds: function(){ return this.getInput().data('upload-cache'); }, getCacheInput: function(){ var paramName = [this.getModel(), this.getMethod(), 'cache'].join('_'); if(!this.getForm().find('#' + paramName).length){ this.getForm().prepend($('', { type: 'hidden', name: this.getModel() + '[' + this.getMethod() + '_cache]', id: paramName, value: (this.isMultiple() ? '[]' : '') })); } return this.getForm().find('#' + paramName); }, createMarkup: function(){ if(!this.getInput().closest('.fallback').length) this.getInput().wrap($('
', { class: 'fallback' })); if(!this.getInput().closest('.dropzone').length) this.getInput().closest('.fallback').wrap($('
', { class: 'dropzone' })); return this; }, createDropzone: function(){ _dz = new Dropzone(this.getInput().closest('.dropzone').addClass(this.getInput().get(0).className).get(0), this.getOptions()); // If the dropzone became a fallback upload input, dz will be a DOM element, not an instance of Dropzone if(_dz instanceof Dropzone){ // Add the dropzone object to the file input, so it's easily accessible this.getInput().data('dropzone', _dz); this.getInput().data('upload', this); // Assign the hidden file input a unique id // Not required outside the test environment, but may // be useful for other reasons in case one needs to get at the hidden inputs $(_dz.hiddenFileInput).attr('id', this.getInput().attr('id') + '_input'); this.addHiddenInputs(); this.addExistingFiles(); _dz.on('sending', $.proxy(this.onBeforeSend, this)); _dz.on('success', $.proxy(this.onSuccess, this)); _dz.on('removedfile', $.proxy(this.onRemove, this)); _dz.on('error', $.proxy(this.onError, this)); Voltron.dispatch('upload:initialized', { upload: this, dropzone: _dz, element: this.getInput().get(0) }); } }, // Add the authenticity token to the request onBeforeSend: function(file, xhr, data){ data.append('authenticity_token', Voltron.getAuthToken()); Voltron.dispatch('upload:sending', { upload: this, form: this.getForm().get(0), file: file, xhr: xhr, data: data, element: this.getInput().get(0) }); // If single file upload dropzone, remove anything that may have been previously uploaded, // change any commit inputs to remove inputs, so the file will be deleted when submitted if(!this.isMultiple()){ $(file.previewElement).closest('.dropzone').find('.dz-preview').each($.proxy(function(index, el){ var id = $(el).data('id'); if(id) this.addRemoval(id); $(el).remove(); }, this)); } }, // Once a file is uploaded, add a hidden input that flags the file to be committed once the form is submitted onSuccess: function(file, data){ for(var i=0; i