Ajax file upload to tmp dir. Add cached_attachment to document. Recover image from cache. Add progress bar.
This commit is contained in:
@@ -1,64 +1,34 @@
|
|||||||
App.Documentable =
|
App.Documentable =
|
||||||
|
|
||||||
initialize: ->
|
initialize: ->
|
||||||
$('input#document_attachment[type=file]').fileupload
|
|
||||||
|
$('input.document_ajax_attachment[type=file]').fileupload
|
||||||
|
|
||||||
add: (e, data) ->
|
add: (e, data) ->
|
||||||
data.progressBar = $('<div class="progress-bar"><div class="loading-bar uploading"></div></div>').insertAfter('#progress-bar')
|
wrapper = $(e.target).parent()
|
||||||
options =
|
$(wrapper).find('.progress-bar-placeholder').empty()
|
||||||
extension: data.files[0].name.match(/(\.\w+)?$/)[0]
|
data.progressBar = $('.progress-bar-placeholder').html('<div class="progress-bar"><div class="loading-bar uploading"></div></div>')
|
||||||
_: Date.now()
|
data.submit()
|
||||||
direct_upload_url = $(this).closest('form').data('direct-upload-url')
|
|
||||||
console.log direct_upload_url
|
|
||||||
|
|
||||||
fileData = new FormData();
|
change: (e, data) ->
|
||||||
fileData.append('file', data.fileInput[0].files[0]);
|
wrapper = $(e.target).parent()
|
||||||
|
$.each(data.files, (index, file)->
|
||||||
console.log direct_upload_url
|
$(wrapper).find('.file-name').text(file.name)
|
||||||
|
)
|
||||||
$.getJSON direct_upload_url, options, (result) ->
|
|
||||||
data.formData = result['fields']
|
|
||||||
data.url = result['url']
|
|
||||||
data.paramName = 'file'
|
|
||||||
data.submit()
|
|
||||||
return
|
|
||||||
|
|
||||||
# $.ajax
|
|
||||||
# url: direct_upload_url
|
|
||||||
# type: 'POST'
|
|
||||||
# data: fileData
|
|
||||||
# cache: false
|
|
||||||
# contentType: false
|
|
||||||
# processData: false
|
|
||||||
# xhr: ->
|
|
||||||
# console.log 'Progress init'
|
|
||||||
# myXhr = $.ajaxSettings.xhr()
|
|
||||||
# if myXhr.upload
|
|
||||||
# # For handling the progress of the upload
|
|
||||||
# myXhr.upload.addEventListener 'progress', ((e) ->
|
|
||||||
# console.log 'progress listener called'
|
|
||||||
# ), false
|
|
||||||
#
|
|
||||||
# myXhr.upload.addEventListener 'complete', ((e) ->
|
|
||||||
# console.log 'complete listener called'
|
|
||||||
# return
|
|
||||||
# ), false
|
|
||||||
# myXhr
|
|
||||||
|
|
||||||
progress: (e, data) ->
|
progress: (e, data) ->
|
||||||
progress = parseInt(data.loaded / data.total * 100, 10)
|
progress = parseInt(data.loaded / data.total * 100, 10)
|
||||||
$('.loading-bar').css 'width', progress + '%'
|
$(data.progressBar).find('.loading-bar').css 'width', progress + '%'
|
||||||
return
|
return
|
||||||
|
|
||||||
done: (e, data) ->
|
done: (e, data) ->
|
||||||
$('.loading-bar').removeClass 'uploading'
|
result = data.response().result
|
||||||
$('.loading-bar').addClass 'complete'
|
if result.status == 200
|
||||||
image =
|
$(data.progressBar).find('.loading-bar').removeClass 'uploading'
|
||||||
id: data.formData.key
|
$(data.progressBar).find('.loading-bar').addClass 'complete'
|
||||||
storage: 'cache'
|
$('#document_cached_attachment').val result.attachment
|
||||||
metadata:
|
else
|
||||||
size: data.files[0].size
|
$(data.progressBar).find('.loading-bar').addClass 'errors'
|
||||||
filename: data.files[0].name.match(/[^\/\\]*$/)[0]
|
$(data.progressBar).prepend("<span>" + result.msg + "</span>")
|
||||||
mime_type: data.files[0].type
|
|
||||||
$('#cached_attachment_data').val JSON.stringify(image)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ App.Forms =
|
|||||||
i = 0
|
i = 0
|
||||||
while i < element.length
|
while i < element.length
|
||||||
element[i].addEventListener 'change', ->
|
element[i].addEventListener 'change', ->
|
||||||
idButton = $(this)
|
$(element).parent().find('.file-name').text(@files[0].name)
|
||||||
idButton.closest('.file-name').find('p').text(@files[0].name)
|
|
||||||
return
|
return
|
||||||
i++
|
i++
|
||||||
|
|
||||||
|
|||||||
@@ -7,18 +7,21 @@
|
|||||||
|
|
||||||
.loading-bar {
|
.loading-bar {
|
||||||
height: 5px;
|
height: 5px;
|
||||||
min-width: 10px;
|
width: 0px;
|
||||||
z-index: 666000666;
|
z-index: 666000666;
|
||||||
-webkit-transition:width 500ms ease-out, height 500ms ease-out;
|
-webkit-transition:width 500ms ease-out, height 500ms ease-out;
|
||||||
-moz-transition:width 500ms ease-out, height 500ms ease-out;
|
-moz-transition:width 500ms ease-out, height 500ms ease-out;
|
||||||
-o-transition:width 500ms ease-out, height 500ms ease-out;
|
-o-transition:width 500ms ease-out, height 500ms ease-out;
|
||||||
transition:width 500ms ease-out, height 500ms ease-out;
|
transition:width 500ms ease-out, height 500ms ease-out;
|
||||||
&.uploading{
|
&.uploading{
|
||||||
background-color: #f00;
|
background-color: #bbb;
|
||||||
}
|
}
|
||||||
&.complete{
|
&.complete{
|
||||||
background-color: #0f0;
|
background-color: #0f0;
|
||||||
}
|
}
|
||||||
|
&.errors{
|
||||||
|
background-color: #f00;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-bar.no-transition {
|
.loading-bar.no-transition {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class DocumentsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
recover_attachment_from_cache
|
||||||
if @document.save
|
if @document.save
|
||||||
flash[:notice] = t "documents.actions.create.notice"
|
flash[:notice] = t "documents.actions.create.notice"
|
||||||
redirect_to params[:from]
|
redirect_to params[:from]
|
||||||
@@ -34,13 +35,13 @@ class DocumentsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def upload
|
def upload
|
||||||
document = Document.new(documentable: @documentable, attachment: params[:file].tempfile, title: "faketitle", user: current_user )
|
document = Document.new(documentable: @documentable, attachment: params[:document][:attachment].tempfile, title: "faketitle", user: current_user )
|
||||||
debugger
|
|
||||||
# We only are intested in attachment validators. We set some fake data to get attachment errors only
|
# We only are intested in attachment validators. We set some fake data to get attachment errors only
|
||||||
if document.valid?
|
if document.valid?
|
||||||
# TODO: Store file on tmp cache
|
# Move image from tmp to cache
|
||||||
msg = { status: 200, msg: "OK" }
|
msg = { status: 200, attachment: params[:document][:attachment].path }
|
||||||
else
|
else
|
||||||
|
params[:document][:attachment].tempfile.delete
|
||||||
msg = { status: 422, msg: document.errors[:attachment].join(', ') }
|
msg = { status: 422, msg: document.errors[:attachment].join(', ') }
|
||||||
end
|
end
|
||||||
render :json => msg
|
render :json => msg
|
||||||
@@ -63,7 +64,14 @@ class DocumentsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def document_params
|
def document_params
|
||||||
params.require(:document).permit(:title, :documentable_type, :documentable_id, :attachment)
|
params.require(:document).permit(:title, :documentable_type, :documentable_id,
|
||||||
|
:attachment, :cached_attachment)
|
||||||
|
end
|
||||||
|
|
||||||
|
def recover_attachment_from_cache
|
||||||
|
if @document.attachment.blank? && @document.cached_attachment.present?
|
||||||
|
@document.attachment = File.open(@document.cached_attachment)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_upload
|
def validate_upload
|
||||||
|
|||||||
@@ -2,11 +2,14 @@ class Document < ActiveRecord::Base
|
|||||||
include DocumentsHelper
|
include DocumentsHelper
|
||||||
include DocumentablesHelper
|
include DocumentablesHelper
|
||||||
has_attached_file :attachment
|
has_attached_file :attachment
|
||||||
|
attr_accessor :cached_attachment
|
||||||
|
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :documentable, polymorphic: true
|
belongs_to :documentable, polymorphic: true
|
||||||
|
|
||||||
validates_attachment :attachment, presence: true
|
# validates_attachment :attachment, presence: true
|
||||||
|
validate :attachment_presence
|
||||||
|
# validates :attachment_prensence
|
||||||
# Disable paperclip security validation due to polymorphic configuration
|
# Disable paperclip security validation due to polymorphic configuration
|
||||||
# Paperclip do not allow to user Procs on valiations definition
|
# Paperclip do not allow to user Procs on valiations definition
|
||||||
do_not_validate_attachment_file_type :attachment
|
do_not_validate_attachment_file_type :attachment
|
||||||
@@ -35,4 +38,10 @@ class Document < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def attachment_presence
|
||||||
|
if attachment.blank? && cached_attachment.blank?
|
||||||
|
errors[:attachment] = I18n.t("errors.messages.blank")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,12 +16,21 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="small-12 column">
|
<div class="small-12 column">
|
||||||
|
<%= f.hidden_field :cached_attachment %>
|
||||||
<%= f.file_field :attachment,
|
<%= f.file_field :attachment,
|
||||||
accept: accepted_content_types_extensions(@document.documentable),
|
accept: accepted_content_types_extensions(@document.documentable),
|
||||||
label: false, class: 'show-for-sr' %>
|
label: false,
|
||||||
|
class: 'document_ajax_attachment show-for-sr',
|
||||||
|
data: {
|
||||||
|
url: upload_documents_url(
|
||||||
|
documentable_type: @document.documentable_type,
|
||||||
|
documentable_id: @document.documentable_id
|
||||||
|
),
|
||||||
|
multiple: false
|
||||||
|
} %>
|
||||||
<%= f.label :attachment, t("documents.form.attachment_label"), class: 'button hollow' %>
|
<%= f.label :attachment, t("documents.form.attachment_label"), class: 'button hollow' %>
|
||||||
<div id="progress-bar" class="progress-bar-placeholder"></div>
|
<div class="progress-bar-placeholder"></div>
|
||||||
<p><%= document_attachment_file_name(@document) %></p>
|
<p class="file-name"><%= document_attachment_file_name(@document) %></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% if @document.errors.has_key?(:attachment) %>
|
<% if @document.errors.has_key?(:attachment) %>
|
||||||
|
|||||||
@@ -936,7 +936,7 @@ ActiveRecord::Schema.define(version: 20170720092638) do
|
|||||||
t.boolean "email_digest", default: true
|
t.boolean "email_digest", default: true
|
||||||
t.boolean "email_on_direct_message", default: true
|
t.boolean "email_on_direct_message", default: true
|
||||||
t.boolean "official_position_badge", default: false
|
t.boolean "official_position_badge", default: false
|
||||||
t.datetime "password_changed_at", default: '2017-07-31 15:04:53', null: false
|
t.datetime "password_changed_at", default: '2017-07-31 21:36:00', null: false
|
||||||
t.boolean "created_from_signature", default: false
|
t.boolean "created_from_signature", default: false
|
||||||
t.integer "failed_email_digests_count", default: 0
|
t.integer "failed_email_digests_count", default: 0
|
||||||
t.text "former_users_data_log", default: ""
|
t.text "former_users_data_log", default: ""
|
||||||
|
|||||||
Reference in New Issue
Block a user