How to preview a loaded image in a "file" input?

11

Description:

I have an example here of how my system is working. EXAMPLE link

HTML

<input type=file>
<input type=button class=hide value="Adicionar outro">

JAVASCRIPT

function verificaMostraBotao(){
    $('input[type=file]').each(function(index){
        if ($('input[type=file]').eq(index).val() != ""){
            $('.hide').show();
        }
    });
}

$('input[type=file]').on("change", function(){
  verificaMostraBotao();
});

$('.hide').on("click", function(){
    $(document.body).append($('<input />', {type: "file" }).change(verificaMostraBotao));
    $('.hide').hide();
});

CSS

input[type=file] {
    float: left;
    display: block;
}
.hide {
    display: none;
    float: left;
}

Need:

I want to implement a preview in this code. Each input display preview on your side;

Is it possible?

    
asked by anonymous 21.02.2014 / 19:53

3 answers

8

You can simply get the value of the input and play as a src of an image, just add this function to your example:

function readURL(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();
        reader.onload = function (e) {
        $(input).next()
        .attr('src', e.target.result)
    };
    reader.readAsDataURL(input.files[0]);
    }
    else {
        var img = input.value;
        $(input).next().attr('src',img);
    }
}

Note (I changed the HTML, I added a <img> of preview for each one):

<input type=file>
<img />
<input type=button class=hide value="Adicionar outro">

I also changed the event $('.hide').on("click") :

$('.hide').on("click", function(){
    $(document.body).append($('<input />', {type: "file" }).change(verificaMostraBotao));
    $(document.body).append($('<img />'));
    $('.hide').hide();
});

Note: Note that I now put a <img> to become the preview of each element.

Call the readURL() function in the .change() event of your input by first checking if the value is empty:

function verificaMostraBotao(){
    $('input[type=file]').each(function(index){
        if ($('input[type=file]').eq(index).val() != ""){
            readURL(this);
            $('.hide').show();
        }
    });
}

JSFiddle Example

Reference

Compatibility:

(@GuilhermeBernal's response reference) - This only works on browsers that support the FileReader API ( which implies in IE10 +)

    
21.02.2014 / 20:06
7

Using the FileReader API (English) , you can read the address that is in input of type file and collect the binary data to later inject on the page:

Function

In the function below, we are reading the content of input of type file and after its completion we create a new DOM element img to which we assign the read data. Finally, we attach the element to the current page, just after the input in question.

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

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

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

Your practical case

For your practical case, in addition to the function above, you need a small change to the code you have, so that the use of the API is also performed on the elements you create dynamically.

Where you are attaching the event change :

$('input[type=file]').on("change", function(){
    verificaMostraBotao();
});

Let's change to a delegation, in this case from body :

$('body').on("change", "input[type=file]", function(){
    verificaMostraBotao();
    readURL(this);
});

Ensuring that new input created by your role can preview the chosen file.

Final Code

The all-together code stays compliant as seen below and in JSFiddle:

Example running on JSFiddle

HTML

<input type="file">
<input type="button" class="hide" value="Adicionar outro">

jQuery

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

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

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

function verificaMostraBotao() {
    $('input[type=file]').each(function(index){
        if ($('input[type=file]').eq(index).val() != "")
            $('.hide').show();
    });
}

$('body').on("change", "input[type=file]", function() {
    verificaMostraBotao();
    readURL(this);
});

$('.hide').on("click", function() {
    $(document.body).append($('<input />', {type: "file" }).change(verificaMostraBotao));
    $('.hide').hide();
});

Credits of the readURL function, in its simplest form, for @Ivan Baev in SOEN in this answer .

    
21.02.2014 / 20:32
5

Knowing that this only works on browsers that support the FileReader API (which implies IE10 +), you can do the following to read the file and as a DataURI, setting the src of an image.

function readImage() {
    if (this.files && this.files[0]) {
        var file = new FileReader();
        file.onload = function(e) {
            document.getElementById("preview").src = e.target.result;
        };       
        file.readAsDataURL(this.files[0]);
    }
}

document.getElementById("imgChooser").addEventListener("change", readImage, false);

Example: JSFiddle .

    
21.02.2014 / 20:06