Hello Rubies,
Do you know how to upload the file through ajax? Last time i was juggling for ajax upload. There is some patch which i have used to allow ajax upload with rails 2.3.x. Follow below instruction to implement it.
Lets, consider the scenario. Where we have content page which has file(.pdf) upload and content area portion.
new.rhtml
<%= form_remote_tag(:url => {:controller => 'contents', :action => 'create'}, :html => { :multipart => true })%>
<p id='error_msgs'> </p>
<p> Content: <%= text_area 'content', 'body' %> </p>
<p> PDF: <%= file_column_field 'content', 'pdf_path' %> </p>
<p> <%= submit_tag('Create') %> </p>
</form>
</form>
This form allow us to create content along with pdf upload through ajax.
Now want to add some basic validation for file?
class Content < ActiveRecord::Base
validates_file_format_of :pdf_path , :in => ["pdf"]
file_column(:pdf_path, :root_path => "#{RAILS_ROOT}/PDFs", :fix_file_extensions => nil)
file_column(:pdf_path, :root_path => "#{RAILS_ROOT}/PDFs", :fix_file_extensions => nil)
end
Above we added the validation for file which must be in .pdf format only and store in our application's PDFs directory. You have to assume that your using file column here otherwise you can use normal file_field as well.
In controller of contents we have method called 'create' which need to enhance.
class ContentsController < ApplicationController
def create
@content = Content.new(params[:content])
responds_to_parent do
if @content.save
render :update do |page|
flash[:notice] = "content created successfully"
page.redirect_to contents_url
end
else
render :update do |page|
page.replace_html "error_msgs", "#{error_messages_for :content}"
end
end
end
responds_to_parent do
if @content.save
render :update do |page|
flash[:notice] = "content created successfully"
page.redirect_to contents_url
end
else
render :update do |page|
page.replace_html "error_msgs", "#{error_messages_for :content}"
end
end
end
end
end
Here you observed something ?.. we have used the responds_to_parent instead of respond_to block.
Now you guys are wondering about method 'responds_to_parent'. correct?
rails_responds_to_parent is the method of gem 'rails_responds_to_parent t'. Now install that via
rails_responds_to_parent is the method of gem 'rails_responds_to_parent t'. Now install that via
gem install rails_responds_to_parent
For the ajax support we have to add the patch called 'remote_upload' in lib folder of rails application
lib/remote_upload.rb
module ActionView
module Helpers
module PrototypeHelper
alias_method :form_remote_tag_old, :form_remote_tag
def form_remote_tag(options = {})
if options[:html] && options[:html][:multipart]
uid = "a#{Time.now.to_f.hash}"
<<-STR
<iframe name="#{uid}" id="#{uid}" src="about:blank" style="position:absolute;left:-100px;width:0px;height:0px;border:0px"></iframe>
<form method="post" action="#{url_for options[:url].update({:iframe_remote => true})}" enctype="multipart/form-data" target="#{uid}" #{%(onsubmit="#{options[:loading]}") if options[:loading]}>
STR
else
form_remote_tag_old(options)
end
end
end
end
end
module Helpers
module PrototypeHelper
alias_method :form_remote_tag_old, :form_remote_tag
def form_remote_tag(options = {})
if options[:html] && options[:html][:multipart]
uid = "a#{Time.now.to_f.hash}"
<<-STR
<iframe name="#{uid}" id="#{uid}" src="about:blank" style="position:absolute;left:-100px;width:0px;height:0px;border:0px"></iframe>
<form method="post" action="#{url_for options[:url].update({:iframe_remote => true})}" enctype="multipart/form-data" target="#{uid}" #{%(onsubmit="#{options[:loading]}") if options[:loading]}>
STR
else
form_remote_tag_old(options)
end
end
end
end
end
This code will override the prototype's form_remote_tag method and allow iframe support.
Now, we have to include below lines in config/environment.rb to allow access of remote_upload and responds_to_parent
require 'remote_upload.rb'
require 'rails_responds_to_parent'
See our work completed. Now we will freely upload the file through ajax. Find interesting?
If you have any suggestion or query then post the comment.
to get the gem source of rails_responds_to_parent
Hi,
ReplyDeleteThank you very much for this posting. It helped me a lot in my application.
Regards,
K. Subrahmanyam
Hey ,
ReplyDeleteYour tutorial is a bit dated. I am using Rails 3 and running into an issue with uploading image file with AJAX form submission . I have the details of it on SO , here : http://stackoverflow.com/questions/16436443/rails-3-image-upload-form-submitting-with-http-instead-of-ajax
Can you help me out with this ? I have been stuck since ever now .
This breaks when the form_remote_tag takes the block form such as:
ReplyDeleteform_remote_tag :url => {...}, :html => {...} do |f|
...
end
Updating the patched "remote_upload.rb" file to accept the block and pass it through is good for the non-multipart case but I'm open to thoughts on how to incorporate it into the multipart "iframe" condition that patch accounts for.