How to preview the user uploaded image with lightbox?

Viewed 133

I'm using touchTouch lightbox library in order to preview the images in a lightbox for a post that user wants to send.

This library is used on my back-end and works flawlessly (since the images are in a folder already), but in the front-end there is a form where the user may upload up to 20 images. The images will show their preview after the user has uploaded them (but before they have sent the form) and I want them to be clickable which would open a lightbox library.

The problem is that the library can't find the images location because they are not uploaded just yet.

I thought about using ajax to upload the images into a temporary folder and then remove the folder and its content once the form is submitted. Could this work (without refreshing the page or submitting the form), or are there any better alternative solutions for this?

JavaScript code to upload the files and show their preview + initialize lightbox library upon loading:

function ImgUpload() {
    var imgWrap = "";
    var imgArray = [];

    $('.upload__inputfile').each(function () {
        $(this).on('change', function (e) {
        imgWrap = $(this).closest('.upload__box').find('.upload__img-wrap');
        var maxLength = $(this).attr('data-max_length');

        var files = e.target.files;
        var filesArr = Array.prototype.slice.call(files);
        var iterator = 0;
        filesArr.forEach(function (f, index) {

            if (!f.type.match('image.*')) {
                return;
            }

            if (imgArray.length > maxLength) {
                return false
            } else {
                var len = 0;
                for (var i = 0; i < imgArray.length; i++) {
                    if (imgArray[i] !== undefined) {
                        len++;
                    }
                }

                if (len > maxLength) {
                    return false;
                } else {
                    imgArray.push(f);

                    var reader = new FileReader();
                    reader.onload = function (e) {
                        var html = "<div class='upload__img-box'><a href='" + f.name + "' class='light-box' data-group='gallery'><div style='background-image: url(" + e.target.result + ")' data-number='" + $(".upload__img-close").length + "' data-file='" + f.name + "' class='img-bg'><div class='upload__img-close'></div></div></a></div>";
                        
                        imgWrap.append(html);
                        iterator++;
                        touchTouch(document.body.querySelectorAll('.light-box')); // Initialize the lightbox library

                        // Ajax script here to upload the images to a temporary folder?
                    }
                    reader.readAsDataURL(f);
                }
            }
        });
    });
});
3 Answers

Basically you could create a data-url from an uploaded image (before uploaded) which will allow you to access it locally and treat it like it was a regular image.

imgInp.onchange = evt => {
  const [...files] = imgInp.files
  if (files) {
    files.forEach(function(file) {
      var img = new Image();
      img.src = URL.createObjectURL(file)
      img.style.width = "200px"
      container.appendChild(img)

      // do your touchTouch initialization on the new elements
      // touchTouch(img);      

      img.onclick = function() {
        alert('lightbox');
      }
    })

  }
}
<form>
  <p>Choose Images, then click for lightbox.</p>
  <input accept="image/*" type='file' id="imgInp" multiple />
</form>

<div id="container">
</div>

Let's try with given code (not tested):

ImgUpload();

function ImgUpload() {
  var imgWrap = "";
  var imgArray = [];

  $('.upload__inputfile').each(function() {
    $(this).on('change', function(e) {
      imgWrap = $(this).closest('.upload__box').find('.upload__img-wrap');
      var maxLength = $(this).attr('data-max_length');

      var files = e.target.files;
      var filesArr = Array.prototype.slice.call(files);
      var iterator = 0;
      filesArr.forEach(function(f, index) {

        if (!f.type.match('image.*')) {
          return;
        }

        if (imgArray.length > maxLength) {
          return false
        } else {
          var len = 0;
          for (var i = 0; i < imgArray.length; i++) {
            if (imgArray[i] !== undefined) {
              len++;
            }
          }

          if (len > maxLength) {
            return false;
          } else {
            imgArray.push(f);

            var object_url = URL.createObjectURL(f)
            var html = "<div class='upload__img-box'><a href='" + f.name + "' class='light-box' data-group='gallery'><div style='background-image: url(" + object_url + ")' data-number='" + $(".upload__img-close").length + "' data-file='" + f.name + "' class='img-bg'><div class='upload__img-close'></div></div></a></div>";
            imgWrap.append(html);
            iterator++;
            setTimeout(function() {
              touchTouch(document.body.querySelectorAll('.light-box')); // Initialize the lightbox library

            });
            // Ajax script here to upload the images to a temporary folder?

          }
        }
      });
    });
  });
}
<form>
  <p>Choose Images, then click for lightbox.</p>
  <input accept="image/*" type='file' id="imgInp" class="upload__inputfile" multiple />
</form>

<div id="container">
</div>

Attempt to convert the data obtained from the File interface to Base64 or DataURL.then set img src='data:image/png;base64str'

Related