user5656315
user5656315

Reputation:

Fill the file details when dropped into input file

I have made a drag and drop file upload. Now when a file is dropped in the drop zone it should fill the data of the dropped file into <input type="file">. How to do it ?

HTML :

<div id='slct'>
  Select file <input type="file" id="filename"
                onchange="readURL(this);" /> <input type="button" value="Upload"
                onclick="sendFile()" /><br> Or
</div>
<button id='uploadDrp'>Upload</button>
<div class="drop">
<div id="filedrag">drop file here</div>
<img src="#" id="prof">
</div>

JavaScript :

   obj.on("dragover", function(e) {
        e.stopPropagation();
        e.preventDefault();
        $(this).css("border", "1px solid #00aaff");
    });
    obj.on("drop", function(e) {
        e.stopPropagation();
        e.preventDefault();
        $(this).css("border", "1px solid #00aaff");
        $("#slct").hide();
        $("#uploadDrp").fadeIn(500);
        var dt = e.originalEvent.dataTransfer;
        file01 = dt;
        var files = dt.files;
        if (dt.files.length > 0) {
            if (dt.files && dt.files[0]) {
                var reader = new FileReader();
                reader.onload = function(e) {
                    $('#prof').attr('src', e.target.result).width(200)
                            .height(200);
                    $('#prof').fadeIn();
                };

                reader.readAsDataURL(dt.files[0]);
            }
        }
    });

Upvotes: 0

Views: 4174

Answers (1)

Endless
Endless

Reputation: 37815

History lession

It s like @adeneo said,

You can't set the value of a file input, due to security restrictions

But in some browser you can set the value to a empty string to clear the field.
In older (IE) browser you need to replace the DOM-node completely

However there is one way to change the input-file-value and that is with another instance of FileList but you do not set the value, instead you set the input.files property: see jsfiddle demo here

I filled a bug report long ago to ask if we could get access to construct a new FileList
We had it globaly in window but there is no way we can use it...

var file1 = new File(['foo'], 'foo.txt')
var file2 = new File(['bar'], 'bar.txt')
new window.FileList([file1, file2]) // throws Illegal constructor

There response was that they are moving towards a normal array instead. It s being descussed here to change it. But there is little to no progress in that field...

Solution

Unfortenly you can not change the value and sumbit the form, Instead you need to create a own FormData and post it using ajax Then you can redirect to the target url...

// Make your own FormData
var fd = new FormData

// Add all drang'n'drop files
for (let file of dt.files) 
  fd.append('files', file)

// Add all input files
for (let file of input.files) 
  fd.append('files', file)

// upload it using xhr or the new fetch api
fetch(targetUrl, {method: 'post', body: fd}).then(redirect)

Code review

if (dt.files.length > 0) {
    // it's unnecessary to have two if statement that checks the same thing
    if (dt.files && dt.files[0]) { 
        // Using FileReader is unnecessary and also worse
        // see this performance test: https://jsfiddle.net/fdzmd4mg/1
        var reader = new FileReader();
        reader.onload = function(e) {
            $('#prof').attr('src', e.target.result).width(200).height(200);
            $('#prof').fadeIn();
        };

        reader.readAsDataURL(dt.files[0]);
    }
}

What i think you should do instead is something like this

if (dt.files && dt.files[0]) {
    // store the file list somehere to upload them later
    // window.files = Array.from(dt.files)
    // window.files = [dt.files[0]]

    let url = URL.createObjectURL(dt.files[0])
    $('#prof').attr('src', url).width(200).height(200);
    $('#prof').fadeIn();
}

Upvotes: 1

Related Questions