Accept nested attributes for documents on proposals. Adapt documentable js file to allow many input files at the same page.
This commit is contained in:
@@ -4,10 +4,14 @@ App.Documentable =
|
|||||||
|
|
||||||
$('input.document_ajax_attachment[type=file]').fileupload
|
$('input.document_ajax_attachment[type=file]').fileupload
|
||||||
|
|
||||||
|
paramName : "document[attachment]"
|
||||||
|
|
||||||
|
formData: null
|
||||||
|
|
||||||
add: (e, data) ->
|
add: (e, data) ->
|
||||||
wrapper = $(e.target).parent()
|
wrapper = $(e.target).parent()
|
||||||
$(wrapper).find('.progress-bar-placeholder').empty()
|
$(wrapper).find('.progress-bar-placeholder').empty()
|
||||||
data.progressBar = $('.progress-bar-placeholder').html('<div class="progress-bar"><div class="loading-bar uploading"></div></div>')
|
data.progressBar = $(wrapper).find('.progress-bar-placeholder').html('<div class="progress-bar"><div class="loading-bar uploading"></div></div>')
|
||||||
data.submit()
|
data.submit()
|
||||||
|
|
||||||
change: (e, data) ->
|
change: (e, data) ->
|
||||||
@@ -26,7 +30,8 @@ App.Documentable =
|
|||||||
if result.status == 200
|
if result.status == 200
|
||||||
$(data.progressBar).find('.loading-bar').removeClass 'uploading'
|
$(data.progressBar).find('.loading-bar').removeClass 'uploading'
|
||||||
$(data.progressBar).find('.loading-bar').addClass 'complete'
|
$(data.progressBar).find('.loading-bar').addClass 'complete'
|
||||||
$('#document_cached_attachment').val result.attachment
|
inputId = '#' + $(e.target).data('chached-attachment-input-field')
|
||||||
|
$(inputId).val result.attachment
|
||||||
else
|
else
|
||||||
$(data.progressBar).find('.loading-bar').addClass 'errors'
|
$(data.progressBar).find('.loading-bar').addClass 'errors'
|
||||||
$(data.progressBar).prepend("<span>" + result.msg + "</span>")
|
$(data.progressBar).prepend("<span>" + result.msg + "</span>")
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ module CommentableActions
|
|||||||
|
|
||||||
def new
|
def new
|
||||||
@resource = resource_model.new
|
@resource = resource_model.new
|
||||||
|
prepare_new_resource_documents
|
||||||
set_geozone
|
set_geozone
|
||||||
set_resource_instance
|
set_resource_instance
|
||||||
end
|
end
|
||||||
@@ -58,6 +59,7 @@ module CommentableActions
|
|||||||
|
|
||||||
def update
|
def update
|
||||||
resource.assign_attributes(strong_params)
|
resource.assign_attributes(strong_params)
|
||||||
|
resource = parse_documents(resource)
|
||||||
if resource.save
|
if resource.save
|
||||||
redirect_to resource, notice: t("flash.actions.update.#{resource_name.underscore}")
|
redirect_to resource, notice: t("flash.actions.update.#{resource_name.underscore}")
|
||||||
else
|
else
|
||||||
@@ -110,4 +112,22 @@ module CommentableActions
|
|||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def prepare_new_resource_documents
|
||||||
|
if @resource.class == Proposal || @resource.class == Budget::Investment
|
||||||
|
(0..@resource.class.max_documents_allowed - 1).each do
|
||||||
|
@resource.documents.build
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_documents(resource)
|
||||||
|
resource.documents.each do |document|
|
||||||
|
document.user = current_user
|
||||||
|
end
|
||||||
|
resource.documents = resource.documents.select{|document| document.valid? }.each do |document|
|
||||||
|
document.attachment = File.open(document.cached_attachment)
|
||||||
|
end
|
||||||
|
resource
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,13 +4,9 @@ class DocumentsController < ApplicationController
|
|||||||
before_filter :prepare_new_document, only: :new
|
before_filter :prepare_new_document, only: :new
|
||||||
before_filter :prepare_document_for_creation, only: :create
|
before_filter :prepare_document_for_creation, only: :create
|
||||||
|
|
||||||
before_filter :validate_upload, only: :upload
|
|
||||||
load_and_authorize_resource :except => [:upload]
|
load_and_authorize_resource :except => [:upload]
|
||||||
skip_authorization_check :only => [:upload]
|
skip_authorization_check :only => [:upload]
|
||||||
|
|
||||||
def preload
|
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
def new
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -35,13 +31,15 @@ class DocumentsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def upload
|
def upload
|
||||||
document = Document.new(documentable: @documentable, attachment: params[:document][:attachment].tempfile, title: "faketitle", user: current_user )
|
attachment = params[:document][:attachment]
|
||||||
|
document = Document.new(documentable: @documentable, attachment: attachment.tempfile, title: "faketitle", user: current_user )
|
||||||
# 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?
|
document.valid?
|
||||||
|
if document.errors[:attachment].empty?
|
||||||
# Move image from tmp to cache
|
# Move image from tmp to cache
|
||||||
msg = { status: 200, attachment: params[:document][:attachment].path }
|
msg = { status: 200, attachment: attachment.tempfile.path }
|
||||||
else
|
else
|
||||||
params[:document][:attachment].tempfile.delete
|
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
|
||||||
@@ -50,7 +48,7 @@ class DocumentsController < ApplicationController
|
|||||||
private
|
private
|
||||||
|
|
||||||
def find_documentable
|
def find_documentable
|
||||||
@documentable = params[:documentable_type].constantize.find(params[:documentable_id])
|
@documentable = params[:documentable_type].constantize.find_or_initialize_by(id: params[:documentable_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def prepare_new_document
|
def prepare_new_document
|
||||||
@@ -74,8 +72,4 @@ class DocumentsController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_upload
|
|
||||||
if @documentable.present?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class ProposalsController < ApplicationController
|
|||||||
|
|
||||||
def create
|
def create
|
||||||
@proposal = Proposal.new(proposal_params.merge(author: current_user))
|
@proposal = Proposal.new(proposal_params.merge(author: current_user))
|
||||||
|
@proposal = parse_documents(@proposal)
|
||||||
|
|
||||||
if @proposal.save
|
if @proposal.save
|
||||||
redirect_to share_proposal_path(@proposal), notice: I18n.t('flash.actions.create.proposal')
|
redirect_to share_proposal_path(@proposal), notice: I18n.t('flash.actions.create.proposal')
|
||||||
@@ -76,7 +77,8 @@ class ProposalsController < ApplicationController
|
|||||||
|
|
||||||
def proposal_params
|
def proposal_params
|
||||||
params.require(:proposal).permit(:title, :question, :summary, :description, :external_url, :video_url,
|
params.require(:proposal).permit(:title, :question, :summary, :description, :external_url, :video_url,
|
||||||
:responsible_name, :tag_list, :terms_of_service, :geozone_id)
|
:responsible_name, :tag_list, :terms_of_service, :geozone_id,
|
||||||
|
documents_attributes: [:cached_attachment, :title] )
|
||||||
end
|
end
|
||||||
|
|
||||||
def retired_params
|
def retired_params
|
||||||
@@ -122,4 +124,5 @@ class ProposalsController < ApplicationController
|
|||||||
def load_successful_proposals
|
def load_successful_proposals
|
||||||
@proposal_successful_exists = Proposal.successful.exists?
|
@proposal_successful_exists = Proposal.successful.exists?
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ module DocumentablesHelper
|
|||||||
documentable.class.accepted_content_types
|
documentable.class.accepted_content_types
|
||||||
.collect{ |content_type| ".#{content_type.split("/").last}" }
|
.collect{ |content_type| ".#{content_type.split("/").last}" }
|
||||||
.join(",")
|
.join(",")
|
||||||
end
|
end
|
||||||
|
|
||||||
def humanized_accepted_content_types(documentable)
|
def humanized_accepted_content_types(documentable)
|
||||||
documentable.class.accepted_content_types
|
documentable.class.accepted_content_types
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
module DocumentsHelper
|
module DocumentsHelper
|
||||||
|
|
||||||
def document_attachment_file_name(document)
|
def document_attachment_file_name(document)
|
||||||
document.attachment.attachment_file_name if document.attachment.exists?
|
document.attachment_file_name if document.attachment.exists?
|
||||||
end
|
end
|
||||||
|
|
||||||
def errors_on_attachment(document)
|
def errors_on_attachment(document)
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ class Document < ActiveRecord::Base
|
|||||||
validate :validate_attachment_size, if: -> { attachment.present? }
|
validate :validate_attachment_size, if: -> { attachment.present? }
|
||||||
validates :title, presence: true
|
validates :title, presence: true
|
||||||
validates :user, presence: true
|
validates :user, presence: true
|
||||||
validates :documentable_id, presence: true
|
# validates :documentable_id, presence: true
|
||||||
validates :documentable_type, presence: true
|
# validates :documentable_type, presence: true
|
||||||
|
|
||||||
def validate_attachment_size
|
def validate_attachment_size
|
||||||
if documentable.present? &&
|
if documentable.present? &&
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class Proposal < ActiveRecord::Base
|
|||||||
documentable max_documents_allowed: 3,
|
documentable max_documents_allowed: 3,
|
||||||
max_file_size: 3.megabytes,
|
max_file_size: 3.megabytes,
|
||||||
accepted_content_types: [ "application/pdf" ]
|
accepted_content_types: [ "application/pdf" ]
|
||||||
|
accepts_nested_attributes_for :documents
|
||||||
|
|
||||||
acts_as_votable
|
acts_as_votable
|
||||||
acts_as_paranoid column: :hidden_at
|
acts_as_paranoid column: :hidden_at
|
||||||
|
|||||||
@@ -22,10 +22,8 @@
|
|||||||
label: false,
|
label: false,
|
||||||
class: 'document_ajax_attachment show-for-sr',
|
class: 'document_ajax_attachment show-for-sr',
|
||||||
data: {
|
data: {
|
||||||
url: upload_documents_url(
|
url: upload_documents_url(documentable_type: @document.documentable_type, documentable_id: @document.documentable_id),
|
||||||
documentable_type: @document.documentable_type,
|
chached_attachment_input_field: "document_cached_attachment",
|
||||||
documentable_id: @document.documentable_id
|
|
||||||
),
|
|
||||||
multiple: false
|
multiple: false
|
||||||
} %>
|
} %>
|
||||||
<%= f.label :attachment, t("documents.form.attachment_label"), class: 'button hollow' %>
|
<%= f.label :attachment, t("documents.form.attachment_label"), class: 'button hollow' %>
|
||||||
|
|||||||
@@ -47,6 +47,35 @@
|
|||||||
<%= f.text_field :external_url, placeholder: t("proposals.form.proposal_external_url"), label: false %>
|
<%= f.text_field :external_url, placeholder: t("proposals.form.proposal_external_url"), label: false %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="small-12 column">
|
||||||
|
<%= f.label :documents %>
|
||||||
|
<p class="help-text">Aquí puedes añadir hasta 3 doucmentos en formato PDF </p>
|
||||||
|
<% @proposal.documents.each_with_index do |document, index| %>
|
||||||
|
<div>
|
||||||
|
<%= f.fields_for :documents, document do |document_fields| %>
|
||||||
|
<%= document_fields.text_field :title %>
|
||||||
|
<%= document_fields.hidden_field :cached_attachment, value: document.attachment.path %>
|
||||||
|
<%= document_fields.file_field :attachment,
|
||||||
|
accept: accepted_content_types_extensions(@proposal),
|
||||||
|
label: false,
|
||||||
|
class: 'document_ajax_attachment show-for-sr',
|
||||||
|
data: {
|
||||||
|
url: upload_documents_url(
|
||||||
|
documentable_type: document_fields.object.documentable_type,
|
||||||
|
documentable_id: document_fields.object.documentable_id
|
||||||
|
),
|
||||||
|
chached_attachment_input_field: "proposal_documents_attributes_#{index}_cached_attachment",
|
||||||
|
multiple: false
|
||||||
|
} %>
|
||||||
|
<%= document_fields.label :attachment, t("documents.form.attachment_label"), class: 'button hollow' %>
|
||||||
|
<div class="progress-bar-placeholder"></div>
|
||||||
|
<p class="file-name"><%= document_attachment_file_name(document) %></p>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="small-12 medium-6 column">
|
<div class="small-12 medium-6 column">
|
||||||
<%= f.label :geozone_id, t("proposals.form.geozone") %>
|
<%= f.label :geozone_id, t("proposals.form.geozone") %>
|
||||||
<%= f.select :geozone_id, geozone_select_options, {include_blank: t("geozones.none"), label: false} %>
|
<%= f.select :geozone_id, geozone_select_options, {include_blank: t("geozones.none"), label: false} %>
|
||||||
|
|||||||
Reference in New Issue
Block a user