Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript dataTransfer and input type=file issue

As part of a piece of work I need to do I am trying to add in a javascript drag and drop feature. Normally with drag and drop on drop one passes the event.dataTransfer.files to an ajax call to an external file (like upload.php) to save the file. However in my case I am needing to integrate it with an existing form that has an <input type="file"> field.

Is there a way to take the event.dataTransfer.files information when one drops a file in to a 'drop zone' and inject it into the <input type="file"> field so that when the form is submitted the file is uploaded (e.g. mimic the click 'browse' on the file field and select a file)?

like image 854
Robert Lyon Avatar asked Jun 04 '13 20:06

Robert Lyon


1 Answers

Yes, input[type=file] is read-only for security reasons. I just solved a similar problem by converting the input[type=file] to an input[type=hidden] and setting the value as the base64 encoded URI of the image.

(Incidentally this works automatically with Paperclip https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/io_adapters/data_uri_adapter.rb )

Here's my jquery code:

$(function() {

  function renderPreviewImageFromFile(e,file) {
    file = file || $(this).prop('files')[0];
    if(file) {
      var img     = $(this).parents('li').find('img.preview');
      var reader = new FileReader();
      reader.onload = function(e) {
        img.attr('src', e.target.result);
      }      
      reader.readAsDataURL(file);
      return img.attr('src');
    }
  }

  $("ul.images-list")
    .on('change','input.file',renderPreviewImageFromFile);

  jQuery.event.props.push("dataTransfer");
  $('.file-drop')
    .on('dragover dragenter', function(e) {
      $(this).addClass('hover');
      e.preventDefault();
      e.stopPropagation();
    }).on('dragleave dragexit', function(e) {
      $(this).removeClass('hover');
      e.preventDefault();
      e.stopPropagation();
    }).on('drop', function(e) {
      $(this).removeClass('hover').find('span').remove();
      e.preventDefault();
      e.stopPropagation();

      // change input into hidden field
      file = e.dataTransfer.files[0];
      input = $(this).parents('li').find('input.file');
      value = renderPreviewImageFromFile.apply(input, [null, file]);
      input.attr('type','hidden').val( value ).parents('div.input').hide();
    });

});
like image 141
David Lowenfels Avatar answered Sep 19 '22 08:09

David Lowenfels