user2784722
user2784722

Reputation: 147

Select and display image(s) using FileReader

Here is my problem, i have this little code to display img that i'm uploading LIVE without reload, but it works only with one img because readURL(input) doesn't have a class and works directly from noname-input, and when i'm adding a class readURL(input.joint), it drops error! Here is my code:

    <input class="joint" type='file' id="imgInp" />
    <img style="width:45px" id="blah" src="#" alt="your image" />


<script type="text/javascript">
function readURL(input) {

    if (input.filers && input.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            $('#blah').attr('src', e.target.result);
        }

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

$("#imgInp").change(function(){
    readURL(this);
});
</script>

I need to add some id or class to this jquery function to make it unique to every input.

What i'm trying to do:

<input class="joint" type='file' id="imgInp" />
        <img style="width:45px" id="blah" src="#" alt="your image" />


    <script type="text/javascript">
    function readURL(input.joint) {

        if (input.joint.filers && input.joint.files[0]) {
            var reader = new FileReader();

            reader.onload = function (e) {
                $('#blah').attr('src', e.target.result);
            }

            reader.readAsDataURL(input.joint.files[0]);
        }
    }

    $("#imgInp").change(function(){
        readURL(this);
    });
    </script>


<input class="file2" type='file' id="imgInp" />
        <img style="width:45px" id="blah" src="#" alt="your image" />


    <script type="text/javascript">
    function readURL(input.file2) {

        if (input.file2.filers && input.file2.files[0]) {
            var reader = new FileReader();

            reader.onload = function (e) {
                $('#blah').attr('src', e.target.result);
            }

            reader.readAsDataURL(input.file2.files[0]);
        }
    }

    $("#imgInp").change(function(){
        readURL(this);
    });
    </script>

Upvotes: 13

Views: 35313

Answers (3)

mVChr
mVChr

Reputation: 50205

Ok, the fact that you are trying to add a class to a function argument with dot notation illustrates that you need to learn more about how Javascript works than can be explained in a simple StackOverflow answer, but let me try:

  • input in readURL(input) is an argument name, similar to a variable name, so you cannot extend it in any way. It is a reference to whatever you pass in when you call readURL, in this case, if you look at the end of your code, it is a reference to this. this refers to the elements referenced by the jQuery selector you passed in: "#imgInp".

So, if you want to use the .joint class instead, just pass that in as a jQuery selector:

$(".joint").change(function(){
    readURL(this);
});
  • However, assuming you have multiple .joint elements, your readURL function will no longer work correctly because it is currently designed to only change the src of #blah. What you need to do is change the src of each elements corresponding img.

So, if you had some HTML like this:

<input class="joint" type='file' />
<img class="joint-img" style="width:45px" src="#" alt="your image" />

<input class="joint" type='file' />
<img class="joint-img" style="width:45px" src="#" alt="your image" />

<input class="joint" type='file' />
<img class="joint-img" style="width:45px" src="#" alt="your image" />

You could place your your readURL function after all the elements and alter the reader.onload section as follows:

function readURL(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            $(input).next('.joint-img').attr('src', e.target.result);
        }

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

$(".joint").change(function(){
    readURL(this);
});

Upvotes: 2

Jivings
Jivings

Reputation: 23262

Your code works correctly for me when I fix the typo:

if (input.filers && input.files[0]) {
          ^^^^^^
if (input.files && input.files[0]) {

Here is the example: http://jsfiddle.net/s6ttw/

Update:

If you want it to work how you expect you need to use classes, rather than ids.

Here's a better example of what you're asking for: http://jsfiddle.net/s6ttw/1/

Upvotes: 1

PSL
PSL

Reputation: 123739

You have duplicate ids all over (imgInp and blah), so the selector will select only the first one, eventually your event is bound only to the first input field and the selection of $('#blah') as well. You need to select the relative image with respect to the input. You dont have to duplicate the script as well. Select the next image tag relative to the input like $(input).next('img').attr('src', e.target.result);

So try:

function readURL(input) {

    if (input.files && input.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            $(input).next('img').attr('src', e.target.result);
        }

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


$(function(){   
    $(".upld").change(function () { //set up a common class
        readURL(this);
    });
});

Fiddle

Upvotes: 14

Related Questions