Jonathan Thurft
Jonathan Thurft

Reputation: 4173

How to append a file into a File Input field

I am trying to create a file drag and drop feature.

I've the drag and drop working from the div and handling the file.

Now I now would like to append this file to the Input[type=file] of the form .

How could I do that?

I tried uploadFormData.append("files[]",f); and derivates but it doesnt work. My debugging was submit the form and check the headers to see if the file was sent.

Could anyone point me in the right direction on how achieve this?

    <form enctype="multipart/form-data" id="yourregularuploadformId">
         <input type="file" name="files[]" multiple="multiple">
    </form>

<script>
      var uploadFormData = new FormData(jQuery("#yourregularuploadformId")[0]);

        function handleFileSelect(evt) {
        evt.stopPropagation();
        evt.preventDefault();

        var files = evt.dataTransfer.files; // FileList object.

        // files is a FileList of File objects. List some properties.

        var output = [];


        for (var i = 0, f; f = files[i]; i++) {
          output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
                      f.size, ' bytes, last modified: ',
                      f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
                      '</li>');
               uploadFormData.append("files[]",f);
        }

        document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
      }
</script>

Upvotes: 2

Views: 21607

Answers (3)

Colonel Thirty Two
Colonel Thirty Two

Reputation: 26569

Create a DataTransfer object, add files via its items field, obtain the FileList of files, then assign it to inputEl.files:

document.getElementById("add-file").addEventListener("click", ev => {
  ev.preventDefault();
  const inputEl = document.getElementById("formfiles");
  
  const dt = new DataTransfer();
  
  // Add items here, possibly from the inputEl's existing list
  dt.items.add(new File(
    ["hello, world!"], "hello_world.txt"
  ));
  
  // Set the input's files
  inputEl.files = dt.files;
});
<input type="file" id="formfiles" name="formfiles" multiple />
<br>
<button id="add-file">Add File Dynamically</button>

Upvotes: 2

NDan
NDan

Reputation: 2162

It is possible to convert file to Base64 (using FileReader) and upload as a string

  var input = document.getElementById('image');

  function readImage(file, callback) {
    var reader = new FileReader();
    reader.onload = function() {
     input.value = reader.result;
    }
    reader.readAsDataURL(file);
  }

Example: https://codepen.io/ndan/pen/KJqZVd

FileReader docs: https://developer.mozilla.org/en-US/docs/Web/API/FileReader/FileReader

ps.

  • Don't store images in Base64 in your DB
  • The best solution is to use direct file upload to the cloud storage (s3, gcloud, etc)

Upvotes: 2

Jaay
Jaay

Reputation: 2153

I'm afraid you can't do it this way because you can't dynamically fill an <input type="file" ....> just because if this was allowed, that mean you can grab any file from the user's computer without any validation.

What you can try to do is bind an event like .change() on your div to trigger when a file is dragged, then make an ajax call on that bind that will upload the file, and finally get the file name (or whatever you want when the upload is finished) from the ajax callback and process it the way you want

Upvotes: 3

Related Questions