Shekhar Joshi
Shekhar Joshi

Reputation: 1008

Javascript FileReader Multiple Images

I am trying to implement javascript's FileReader Interface in my project.

The requirement: There is a file input field which is "multiple" enabled, I want the user should select a few images and should see the images on the page even before hitting submit(so that (s)he may delete it if (s)he wants!). But the problem is that only one image is displayed on the screen. The tags are created but the src is empty except for the last image.

The code:

<html>
<head>
    <meta charset="windows-1252">
    <title></title>
</head>
<body>
    <div>
        <form action="upload.php" method="post" enctype="multipart/form-data">
            <input type="file" name="abc[]" multiple/>
            <input type="submit"/>
        </form>
    </div>
<img id="image0"/>
</body>

<script src="resources/js/jquery-2.1.3.min.js" type="text/javascript"></script>
<script>
    $('document').ready(function () {
        $("input[name='abc[]']").change(function (e) {
            console.log(e.originalEvent.srcElement.files.length);
            for (var i = 1; i <= e.originalEvent.srcElement.files.length; i++) {

                var file = e.originalEvent.srcElement.files[i-1];
                var img = document.createElement("img");
                img.id = "image"+i;
                var reader = new FileReader();
                reader.onloadend = function () {
                    img.src = reader.result;
                }
                reader.readAsDataURL(file);
                $("#image"+(i-1)).after(img);
            }
        });
    });
</script>

For Example, in the image selection popup if I have selected img1. img2 and img3, only img3 is displayed. however, on hitting submit I do get all the images at the server side: enter image description here

What am I missing here?

Upvotes: 4

Views: 6307

Answers (1)

Musa
Musa

Reputation: 97717

Have a look at How do JavaScript closures work?

Your for onloadend callback is going to fire after the for loop completes, therefore img will be set to the last image element created when onloadend fires for each FileReader you created. A simple workaround to this closure issue is to use an IIFE to return a function that uses the value of the img variable at that instant in the loop to use as the handler

            reader.onloadend = (function (img) {
                return function(){
                    img.src = reader.result;
                };
            })(img)

or use JQuery's each

        $.each(e.originalEvent.srcElement.files, function(i, file) {

            var img = document.createElement("img");
            img.id = "image"+(i+1);
            var reader = new FileReader();
            reader.onloadend = function () {
                img.src = reader.result;
            }
            reader.readAsDataURL(file);
            $("#image"+i).after(img);
        });

Upvotes: 7

Related Questions