3

I'm using Vich Uploader Bundle to submit one image per form, I'd like to be able to display a thumbnail of the image before it's uploaded because as it is, the image is uploaded and nothing is shown or done to indicate that anything happened. I tried setting inject_on_load to true but this just puts the url of the image in the element that it appears.

config.yml

# Vich File Uploader
vich_uploader:
    db_driver: orm

    mappings:
        image:
            uri_prefix:         /uploads/listings/images
            upload_destination: '%kernel.root_dir%/../web/uploads/listings/images'
            namer:              vich_uploader.namer_uniqid
            inject_on_load:     false
            delete_on_update:   true
            delete_on_remove:   true
        avatar_image:
            uri_prefix:         /uploads/avatars
            upload_destination: '%kernel.root_dir%/../web/uploads/avatars'
            namer:              vich_uploader.namer_uniqid
            inject_on_load:     false
            delete_on_update:   true
            delete_on_remove:   true

        agency_logo:
            uri_prefix:         /uploads/avatars
            upload_destination: '%kernel.root_dir%/../web/uploads/avatars'
            namer:              vich_uploader.namer_uniqid
            inject_on_load:     false
            delete_on_update:   true
            delete_on_remove:   true
Dan185
  • 356
  • 3
  • 12

2 Answers2

4

Here is a simple example using jquery library :

in your template , we suppose you are including your jquery library using for example :

<script src="jquery.min.js"></script>

fill the correct url to the ressource jquery in your project .

let's create a simple js function :

function filePreview(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();
        reader.onload = function (e) {
            $('#uploadForm + img').remove();
            $('#uploadForm').after('<img src="'+e.target.result+'" width="450" height="300"/>');
        }
        reader.readAsDataURL(input.files[0]);
    }
}

JavaScript FileReader is used to read the content of the file in filePreview() function

If you want to preview all type of file, use <embed> tag instead of <img> tag.

Place the following code in the reader.onload event and remove the existing code:

$('#uploadForm + embed').remove();
$('#uploadForm').after('<embed src="'+e.target.result+'" width="450" height="300">');

Now call the filePreview() method on change the file input:

$("#file").change(function () {
    filePreview(this);
});

your Html is seem something like that :

<form method="post" action="upload.php" enctype="multipart/form-data" id="uploadForm">
    <input type="file" name="file" id="file" />
    <input type="submit" name="submit" value="Upload"/>
</form>
andreaem
  • 1,635
  • 2
  • 20
  • 49
Yassine CHABLI
  • 3,459
  • 2
  • 23
  • 43
  • 1
    This works, seems like it freezes the browser for a moment on Firefox though, I don't think it's an issue on Chrome, could be too that I'm on Linux Firefox. I recall using dropzone (3rd party js library) that did the same thing as this, kind of froze the browser on FF for a bit, but not Chrome. – Dan185 Oct 02 '18 at 16:52
2

I went with URL.createObjectURL() because it doesn't cause any freezing in Firefox, I found the below snippet works pretty well for Vich particularly.

  // Preview image thumbnail on upload for vich
  $.fn.previewImage = function() {
    $(this).change(function(e) {
      var url = URL.createObjectURL(e.target.files[0]);
      $(this).parents('.vich-image').children('img').remove();
      $(this).parents('.vich-image').prepend('<img class="preview_image" src="' + url + '"/>');
    })
  }
  $('#profile_avatarImage_file').previewImage();
  $('#profile_logo_file').previewImage();
Dan185
  • 356
  • 3
  • 12