1

I am trying make an html5 image uploader but html5 has problems with multiple upload.

This is the script I use:

function makeFileList() {
        var input = document.getElementById("filez");
        var ul = document.getElementById("file_wrap_list");
        while (ul.hasChildNodes()) {
            ul.removeChild(ul.firstChild);
        }
        for (var i = 0; i < input.files.length; i++) {
            var j = i+1;
            var li = document.createElement("li");
            li.innerHTML = j+'. '+input.files[i].name;
            ul.appendChild(li);
        }
        if(!ul.hasChildNodes()) {
            var li = document.createElement("li");
            li.innerHTML = 'No Files Selected';
            ul.appendChild(li);
        }
    }

the HTML tag:

<input type="file" name="photo[]" id="filez" multiple onchange="makeFileList();"/>

then on submit I upload and add the images in mysql table. I thought about chaning the js script so that every time iamges are selected they are going to create hidden inputs and normally show their names so that clients know what they have selected. and then after submiting the form the images are going to be uploaded, but I don't know if it is going to work in practice and my idea seems a bit odd. I would like to know if anyone has any suggestion on how to alter the js script so that everytime a user clicks and selectes images the script to register the images in array. Or any other idea is welcome.

2 Answers 2

1

Your idea about the array is a good one. The problems then are making sure the user hasn't already selected a file, and allowing them to remove files they've previously selected. The difficult part is in reliably comparing files.

I tweaked your code and managed to get it working here.

// An array to store file references in
var files = [];

// Look in files to see if it's already in there
function alreadySelected( newFile ){
    var match = false;

    // We can't just use files.indexOf( newFile ), since JS can't test file equality
    files.forEach( function compareProperties( oldFile ){
        var key;
        var oldProp;
        var newProp;

        for ( key in newFile ){
            if( newFile.hasOwnProperty( key ) ){
                oldProp = oldFile[ key ];
                newProp = newFile[ key ];

                if( newProp !== oldProp ){
                    // The root of the problem: the same date will be a different date object.
                    if( newProp instanceof Date ){
                        if( newProp.getTime() !== oldProp.getTime() ){
                            return;
                        }
                    }
                    else {
                        return;
                    }
                }
            }
        }

        match = true;
    } );

    return match;
}

window.makeFileList = function makeFileList() {
    var input = document.getElementById("filez");
    var ol    = document.getElementById("file_wrap_list");

    Array.prototype.forEach.call( input.files, function processFile( file ){
        // If the user's already added this file to the list, move on to the next.
        if( alreadySelected( file ) ){
            return;
        }

        var li = document.createElement("li");
        // We'll also create an 'X' link for users to remove files from the list
        var a  = document.createElement("a");

        li.innerHTML = file.name;
        a.innerHTML  = "X";

        a.addEventListener( "click", function removeFile( clickEvent ){
            clickEvent.preventDefault();

            // Find the file in the array and remove it
            files.splice( files.indexOf( file ), 1  );
            ol.removeChild( li );
        }, false ) ;

        files.push( file );

        li.appendChild( a );
        ol.appendChild( li );
    } );

    // Reset the value. Normal file inputs won't trigger the change event if the value is the same,
    // but a user might add a file, delete it, then try to add it again.
    input.value = '';
};
Sign up to request clarification or add additional context in comments.

5 Comments

Your script works perfectly on the client side, now I am trying to make it work on the server side because for some reason when I submit the form the image post data go empty in the server side
I tried console.log(files) and it gives the array. but I think the problem might be the window.makeFileList because it sends the array not list FileList
I found the problem, the last line: input.value = ''; always sent empty array data of the files. I deleted it and now it works. But there must be a work around it just deleting it is not a solution, any ideas?
Your original problem was that a file input couldn't select files from multiple folders, which is why we're adding files to an array. You don't want to send the contents of the file input, because it can only ever get files from one folder. Instead, you want to send each file in the files array. You suggested the array idea yourself!
I went to your link and even though it worked perfectly on jsfiddle, it only worked for me (in my code) if I removed the check 'hasOwnProperty' on line 15. For some reason, the hasOwnProperty check always evaluated to false so I could never add more than one file at a time.
0

I believe this question is similar to another I recently attempted to answer. The link for my solution is here: HTML multiple file upload from different folders.

Using HTML and jQuery, I was able to create a form where you could add multiple "browser" buttons dynamically. I also provided a PHP solution for handling the data server-side!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.