diff --git a/app/assets/javascripts/s3_direct_upload.js.coffee b/app/assets/javascripts/s3_direct_upload.js.coffee index 05858d8..3f62b4e 100644 --- a/app/assets/javascripts/s3_direct_upload.js.coffee +++ b/app/assets/javascripts/s3_direct_upload.js.coffee @@ -12,7 +12,7 @@ $.fn.S3Uploader = (options) -> return this - $uploadForm = this + $uploaderElement = this settings = path: '' @@ -32,8 +32,9 @@ $.fn.S3Uploader = (options) -> form.submit() for form in forms_for_submit false - setUploadForm = -> - $uploadForm.fileupload + setUploadElement = -> + $uploaderElement.fileupload + url: settings.url if settings.url add: (e, data) -> file = data.files[0] @@ -42,14 +43,14 @@ $.fn.S3Uploader = (options) -> unless settings.before_add and not settings.before_add(file) current_files.push data data.context = $($.trim(tmpl("template-upload", file))) if $('#template-upload').length > 0 - $(data.context).appendTo(settings.progress_bar_target || $uploadForm) + $(data.context).appendTo(settings.progress_bar_target($(this)) || $uploaderElement) if settings.click_submit_target forms_for_submit.push data else data.submit() start: (e) -> - $uploadForm.trigger("s3_uploads_start", [e]) + $uploaderElement.trigger("s3_uploads_start", [e]) progress: (e, data) -> if data.context @@ -57,38 +58,37 @@ $.fn.S3Uploader = (options) -> data.context.find('.bar').css('width', progress + '%') done: (e, data) -> - content = build_content_object $uploadForm, data.files[0], data.result + content = build_content_object $uploaderElement, data.files[0], data.result - to = $uploadForm.data('callback-url') + to = $uploaderElement.data('callback-url') if to - content[$uploadForm.data('callback-param')] = content.url + content[$uploaderElement.data('callback-param')] = content.url + element = $(this) $.ajax - type: $uploadForm.data('callback-method') + type: $uploaderElement.data('callback-method') url: to data: content - beforeSend: ( xhr, settings ) -> $uploadForm.trigger( 'ajax:beforeSend', [xhr, settings] ) - complete: ( xhr, status ) -> $uploadForm.trigger( 'ajax:complete', [xhr, status] ) - success: ( data, status, xhr ) -> $uploadForm.trigger( 'ajax:success', [data, status, xhr] ) - error: ( xhr, status, error ) -> $uploadForm.trigger( 'ajax:error', [xhr, status, error] ) - - # $.post(to, content) + beforeSend: ( xhr, settings ) -> element.trigger( 'ajax:beforeSend', [xhr, settings] ) + complete: ( xhr, status ) -> element.trigger( 'ajax:complete', [xhr, status] ) + success: ( data, status, xhr ) -> element.trigger( 'ajax:success', [data, status, xhr] ) + error: ( xhr, status, error ) -> element.trigger( 'ajax:error', [xhr, status, error] ) data.context.remove() if data.context && settings.remove_completed_progress_bar # remove progress bar - $uploadForm.trigger("s3_upload_complete", [content]) + $uploaderElement.trigger("s3_upload_complete", [content]) current_files.splice($.inArray(data, current_files), 1) # remove that element from the array - $uploadForm.trigger("s3_uploads_complete", [content]) unless current_files.length + $uploaderElement.trigger("s3_uploads_complete", [content]) unless current_files.length fail: (e, data) -> - content = build_content_object $uploadForm, data.files[0], data.result + content = build_content_object $uploaderElement, data.files[0], data.result content.error_thrown = data.errorThrown data.context.remove() if data.context && settings.remove_failed_progress_bar # remove progress bar - $uploadForm.trigger("s3_upload_failed", [content]) + $uploaderElement.trigger("s3_upload_failed", [content]) formData: (form) -> - data = form.serializeArray() + data = $('.s3upload_hidden_fields').serializeArray() fileType = "" if "type" of @files[0] fileType = @files[0].type @@ -101,15 +101,15 @@ $.fn.S3Uploader = (options) -> data[1].value = settings.path + key data - build_content_object = ($uploadForm, file, result) -> + build_content_object = ($uploaderElement, file, result) -> content = {} if result # Use the S3 response to set the URL to avoid character encodings bugs content.url = $(result).find("Location").text() content.filepath = $('').attr('href', content.url)[0].pathname - else # IE <= 9 return a null result object so we use the file object instead - domain = $uploadForm.attr('action') - content.filepath = settings.path + $uploadForm.find('input[name=key]').val().replace('/${filename}', '') - content.url = domain + content.filepath + '/' + encodeURIComponent(file.name) + #else # IE <= 9 return a null result object so we use the file object instead + #domain = $uploaderElement.attr('action') + #content.filepath = settings.path + $uploaderElement.find('input[name=key]').val().replace('/${filename}', '') + #content.url = domain + content.filepath + '/' + encodeURIComponent(file.name) content.filename = file.name content.filesize = file.size if 'size' of file @@ -120,7 +120,7 @@ $.fn.S3Uploader = (options) -> #public methods @initialize = -> - setUploadForm() + setUploadElement() this @path = (new_path) -> diff --git a/lib/s3_direct_upload/form_helper.rb b/lib/s3_direct_upload/form_helper.rb index 0cde2d1..e5ea92c 100644 --- a/lib/s3_direct_upload/form_helper.rb +++ b/lib/s3_direct_upload/form_helper.rb @@ -4,11 +4,23 @@ def s3_uploader_form(options = {}, &block) uploader = S3Uploader.new(options) form_tag(uploader.url, uploader.form_options) do uploader.fields.map do |name, value| - hidden_field_tag(name, value) + hidden_field_tag(name, value, :class => "s3upload_hidden_fields") end.join.html_safe + capture(&block) end end + def s3_uploader_hidden_fields(options = {}, &block) + uploader = S3Uploader.new(options) + (uploader.fields).map do |name, value| + hidden_field_tag(name, value, :class => "s3upload_hidden_fields") + end.join.html_safe + end + + def s3_uploader_field(options = {}) + uploader = S3Uploader.new(options) + file_field_tag(:file, uploader.field_options).html_safe + end + class S3Uploader def initialize(options) @key_starts_with = options[:key_starts_with] || "uploads/" @@ -31,19 +43,33 @@ def initialize(options) def form_options { - id: @options[:id], - class: @options[:class], method: "post", authenticity_token: false, multipart: true, + }.merge(field_options) + end + + def field_options + form_data_options.merge(form_preset_options) + end + + def form_data_options + { data: { - callback_url: @options[:callback_url], - callback_method: @options[:callback_method], - callback_param: @options[:callback_param] + callback_url: @options[:callback_url], + callback_method: @options[:callback_method], + callback_param: @options[:callback_param] }.reverse_merge(@options[:data] || {}) } end + def form_preset_options + { + id: @options[:id], + class: @options[:class], + } + end + def fields { :key => @options[:key] || key, @@ -72,7 +98,6 @@ def policy_data { expiration: @options[:expiration], conditions: [ - ["starts-with", "$utf8", ""], ["starts-with", "$key", @options[:key_starts_with]], ["starts-with", "$x-requested-with", ""], ["content-length-range", 0, @options[:max_file_size]],