Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to POST files from HTML5 Drag-Drop to a Rails 3 App & Paperclip?

I'm trying to get some html5 drag-and-drop functionality in a Rails 3 app with Paperclip. So, basically:

  1. One or more files are dragged and dropped onto a DIV
  2. Files are POST'ed to a Rails action (together or one at a time)
  3. Rails action saves each files as a new attachment in Paperclip

Right now the only way I can get this working is by sending an XMLHttpRequest with the File data and having my Rails action read the request.raw_post ... this isn't a workable solution because I need to send along additional POST params and the authenticity token.

Here's what I have so far:

<!-- IN MY VIEW -->
<h2>Drag and drop upload</h2>

<div id="drop">
  <h2>Drop Files Here</h2>
</div>

<script type="text/javascript" charset="utf-8">
  var dropbox = document.getElementById("drop");  
  drop = function(evt) {   
    evt.stopPropagation();
    evt.preventDefault();
    var files = evt.dataTransfer.files;
    var count = files.length;
    if (count > 0) {
        // handleFiles(files);
      var url = '/images/raw';
      var request = new XMLHttpRequest();
      request.open("POST",  url, true); // open asynchronous post request
      request.send(files[0]);
    }
  }
  dragEnter = function(evt) {
    evt.stopPropagation();
    evt.preventDefault();
  }
  dragExit = function(evt) {
    evt.stopPropagation();
    evt.preventDefault();
  }
  dragOver = function(evt) {
    evt.stopPropagation();
    evt.preventDefault();
  }
  // init event handlers
  dropbox.addEventListener("dragenter", dragEnter, false);
  dropbox.addEventListener("dragexit", dragExit, false);
  dropbox.addEventListener("dragover", dragOver, false);
  dropbox.addEventListener("drop", drop, false);
</script>

And my controller action:

class ImagesController < ApplicationController

  # ... Normal REST actions 

  def raw
    name = "tmp_image.png"
    data = request.raw_post
    @file_content = File.open("#{Rails.root.to_s}/tmp/#{name}", "wb") do |f| 
      f.write(data)
    end
    @image = Image.new(:attachment => File.new("#{Rails.root.to_s}/tmp/#{name}"))
    @image.save
    File.unlink("#{Rails.root.to_s}/tmp/#{name}")
    render :text => 'success'    
  end
end

So, what's the proper way to POST drag-and-drop files to my app with additional params?

(If it helps, I have the entire experiment as a public GitHub repo here)

like image 478
Callmeed Avatar asked Sep 21 '10 22:09

Callmeed


1 Answers

Have a look at

https://github.com/blueimp/jQuery-File-Upload/wiki

and scroll down to Ruby (on Rails). That probably is exactly what you are looking for, including a tutorial on how to use it with Rails 3 and paperclip. And from my own experiences it works like a charm.

And as Joost commented: https://github.com/yortz/carrierwave_jquery_file_upload shows a nice example of how to combine carrierwave with jquery_file_upload

like image 58
Ingo Avatar answered Oct 02 '22 22:10

Ingo