My friends often asked me how to upload file using AJAX, and usually they got answer “in no way”. Correct answer, but what if I need to upload file without full page reloading? And, of course, I want to use RJS in this case. Here I’ll explain what to do to get effect very similar to AJAX file upload (btw, Gmail uses this technique).
First of all, do you know, that form element has attribute target? If you specify it your form will be submitted into frame with name entered in target attribute. Of course, this frame can be iframe, and it can be hidden! Look at the following chunk of HTML code:
1 2 3 4 5 | <form target="upload_frame" action="/test/upload_action" id="upload_form" method="post" enctype="multipart/form-data"> <input type="file" name="uploaded_file" /><br /> <input type="submit" /> </form> <iframe id="upload_frame" name="upload_frame" style="display: none"></iframe> |
When you click the “Submit” button, form will be submitted to hidden iframe and controller’s action will be called. But resulting RJS will be returned into the hidden frame! We need to get full respond and execute it in context of whole page (parent window for our frame). There is one interesting technique exists: http://developer.apple.com/internet/webcontent/iframe.html, and it’s implementation as Ruby on Rails plugin here. Example of using:
1 2 3 4 5 6 7 8 9 10 11 | class TestController < ActionController::Base def upload_action # Do stuff with params[:uploaded_file] responds_to_parent do render :update do |page| page.replace_html 'upload_form', :partial => 'upload_form' end end end end |
It’s simple, right?
[…] In this short story author describes how to implement file upload without full page reloading (technique used in gmail) with Ruby on Rails.read more | digg story Share and Enjoy:These icons link to social bookmarking sites where readers can share and discover new web pages. […]
Классная статья, спору нет. Созрел только небольшой вопросик как отследить загрузился ли файл на сервер, ведь существует куча преград при загрузке (размер файла превышает разрешенный и т.п.). Отдавать с сервера страницу с JavaScript, который бы дернул функцию на странице как то не красиво (да и не всегда сработает), а как узнать кроссбраузерно что пришло в теле страницы с сервера для меня загадка, если не сложно прошу расширения статьи.
Попробуем применить на практике. Еще было бы интересно состыковать эту штуку с плагином upload_progress
Ага, были такие мысли, займусь на досуге.
[…] There is no way to upload files using AJAX. How Gmail does it then? Well, the answer is using <iframe>. Here is a post that describe this technique in detail. Infact we at Vinayak Solutions are using this technique from months, obviously inspired by Gmail. ;-) […]
Добавлю только, что для проверки статуса достаточно запустить интервалом в секунду калбэк функцию (я о javascript говорю), которая будет смотреть readyState у окна в скрытом фрейме.
По поводу прогресса загрузки файла, посмотрите статью Юрия Рашковского RubyOnRails: AJAX File Upload Hint.
Спасибо, погляжу
По поводу загрузки файлов без обновления, напоминаю прекрасную библиотеку dklab.ru
http://dklab.ru/lib/JsHttpRequest/
Версия 4.0
я уже писал как то про неё, но эффекта было ноль. И вот… получите и спокойно пользуйтесь. На сегодня я думаю это самое лучшее реализация технологии AJAX. И тем паче загрузки файлов без перезагрузки страницы !!!
Это не реклама… я сам давно пользуюсь и не я её писал.
[…] There is no way to upload files using AJAX. How Gmail does it then? Well, the answer is using <iframe>. Here is a post that describe this technique in detail. Infact we are using this technique from months, obviously inspired by Gmail. […]
great article! its a tricky problem but your solution works like a charm ;-)
Thanks for the help but from the Apple site, %{style=”display: none”} doesn’t work on the iframe but if you set it to %{style=”height:0;width:0;border:0;”} then it will work.
Hey, nice article.. I actually wrote a plugin that does this. I’m using it in a couple places, but had to write it so quickly that I wasn’t able to adequately test it on all platforms. You can check it out here: http://rubyforge.org/projects/remote-upload/
Please tell me what you think
[…] Dmytro Shteflyuk’s Home » In-place file upload with Ruby on Rails (tags: ruby rubyonrails rails tutorial reference howto) […]
I’m using your code almost exactly and most of it seems to be working, but when i try to do something with the uploaded_file all it has is the filename, not the actual file data. Any ideas?
Rails Developer, great thanks for the tip!
Jeff, great news! Will check your plugin in short time. Thanks!
Great article! Thanks! I’ve combined your solution with attachment_fu plugin and result is awesome! Thanks!
Спасибо а идею реализации. Думаю что этой техникой можно пользотаться и в других случаях.
Seems as though the problem with the lack of data being transfered is a problem with Firefox. When I use ff the files are always empty, however when I use Exploder, the data is carried over.
this solution only seems to work on txt files. Formatting for PDFs and Word Docs were hosed.
Alright, that was because I was trying to do it with remote_form instead of a form_for. Only the text was making it through. BTW what was the name of the plugin that was used for returning js to the iframe? That link is dead.
The above mentioned plugin is: respondes_to_parent
jeffguroo, you right
It’s impossible to upload file using AJAX’s XMLHttpRequest. So I have written this post to show how to do it using iframe.
Thanks for comment about broken link, I have fixed it.
after beeting my head against this all day, I have found that doing a simple
also works quite well in Rails v1.2.3 and the acts_as_attachment plugin. Thanks for the file upload/AJAX workaround… a lifesaver.
All you really need is the first part. The form’s target=”IFrameName” is all that really matters.
As far as the IFrame. You can give it a width and height, and then any text that you generate in the php upload file will show there.
Really simple.
Hi I have tried this in my app. In my app, I have a partial to display my form to upload files and in another partial i am listing the files uploaded. right now I have to redirect the page after uploading the files. But how display my file list partial initially and update it with adding the newly added file info every time i upload a new file…
any help appreciated
regards,
venkat
[…] In-place file upload with Ruby on Rails – The GMail technique for asynchronous uploads. […]
[…] In-place file upload with Ruby on Rails – The GMail technique for asynchronous uploads. […]
Вот здесь
http://www.rubyf.info/blog/show/3
подробно рассмотрена данная тема с примерами.
[…] http://kpumuk.info/ruby-on-rails/in-place-file-upload-with-ruby-on-rails/ […]
Есть плугин для jQuery, который использует похожую технику.