Search code examples
javascriptjqueryjquery-file-upload

Upload Preview Script Issue


I have a problem with my upload preview script which I can't find. Whenever I click on the upload image button and select for example 3 images at once, It uploads without a giving an error all the images to my database. But When I choose the images one by one, It just uploads, one image to my database.

I tried to test it using echo count($_files) and exit function and it's clearly not the php part having a problem.

var count = 0;

function handleFileSelect(evt) {
  var $fileUpload = $("input#Photofile[type='file']");
  count = count + parseInt($fileUpload.get(0).files.length);

  if (parseInt($fileUpload.get(0).files.length) > 4 || count > 3) {
    alert("You can only upload a maximum of 3 photos");
    count = count - parseInt($fileUpload.get(0).files.length);
    evt.preventDefault();
    evt.stopPropagation();
    return false;
  }
  var files = evt.target.files;
  for (var i = 0, f; f = files[i]; i++) {
    if (!f.type.match('image.*')) {
      continue;
    }
    var reader = new FileReader();

    reader.onload = (function(theFile) {
      return function(e) {
        var span = document.createElement('span');
        span.innerHTML = ['<img class="thumb mrm mts" src="', e.target.result, '" title="', escape(theFile.name), '"/><span class="remove_img_preview"></span>'].join('');
        document.getElementById('list').insertBefore(span, null);
      };
    })(f);

    reader.readAsDataURL(f);
  }
}

$('#Photofile').change(function(evt) {
  handleFileSelect(evt);
});

$('#list').on('click', '.remove_img_preview', function() {
  $(this).parent('span').remove();

  //this is not working...
  var i = array.indexOf($(this));
  if (i != -1) {
    array.splice(i, 1);
  }
  // tried this too:
  //$(this).parent('span').splice( 1, 1 );

  count--;
});
form .post-image-collection {
  margin: -20px 0px 0px -20px;
  overflow: hidden;
}

form .post-image {
  position: relative;
  float: left;
  height: 152px;
  width: 170px;
  background: #f2f2f2;
  border: 1px dashed #ccc;
  padding: 0;
  border-radius: 4px;
  text-align: center;
  cursor: pointer;
}

.mrm {
  margin-right: 20px;
}

.mts {
  margin-top: 10px;
}

form .post-image img {
  max-width: 80px;
  max-height: 80px;
  width: auto;
  height: auto;
  vertical-align: top;
  border-radius: 3px;
  overflow: hidden;
}

form .post-image .icon-camera {
  display: none;
}

form .post-image input {
  position: absolute;
  z-index: 2;
  opacity: 0;
  width: 100%;
  height: 100%;
}

form .post-image.empty {
  position: relative;
  float: left;
  height: 130px;
  width: 130px;
  background: #f2f2f2;
  border: 1px dashed #ccc;
  padding: 0;
  border-radius: 4px;
  text-align: center;
  cursor: pointer;
  vertical-align: top;
}

form .post-image.empty .icon-camera {
  display: block;
  height: 30px;
  line-height: 30px;
  left: 40%;
  position: absolute;
  text-align: center;
  top: 50%;
  width: 30px;
  cursor: inherit;
  margin: -15px 0px 0px -15px;
}

form .post-image.empty .icon-camera img {
  height: 60px;
  width: 60px;
}

form .post-image.empty input {
  cursor: pointer;
}

form .post-image p,
.file_container-orange p {
  margin: 10px 0;
  margin: 1rem 0;
  text-align: center;
  font-family: "OpenSansSemiBold", sans-serif;
}

.uppercase {
  text-transform: uppercase;
}

#list {
  float: left;
}

.thumb {
  height: 130px;
  width: 130px;
  margin-right: 20px;
  margin-top: 10px;
}

.remove_img_preview {
  position: relative;
  top: -46px;
  right: 40px;
  font-size: 20px;
  line-height: 1;
  padding: 4px 6px;
  background: white;
  border-radius: 0px 0px 0px 3px;
  text-align: center;
  cursor: pointer;
}

.remove_img_preview:before {
  content: "×";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <div class="row row-images">
    <label for="image">Images*</label>
    <div class="column image_container">
      <div class="post-image-collection">
        <label id="list"></label>
        <label class="post-image post-image-placeholder mrm mts empty">
          <input type="file" id="Photofile" name="images[]" required="required" multiple />
          <span class="icon-camera"><img src="https://cdn.onlinewebfonts.com/svg/img_134042.png"></span>
          <p class="uppercase">Photo</p>
        </label>
      </div>
    </div>
</form>

Please can someone check my script and tell me what might be the problem?


Solution

  • Something like this might work (I didn't correct the part of the image removal, it continues raising an exception as before, I just worked on the file upload part).

    Note that on the server side you might receive various $_FILE inputs, named images_X (X being any number starting by 1), each one having zero or more images.

    var count = 0;
    
    function addPhotoSelector() {
      // Hide the current image selectors
      $('.post-image.post-image-placeholder').hide();
      // Update the number of image selectors
      var $num_images = $("#imagenum");
      var num_images = $num_images.val()+1;
      $num_images.val(num_images);
      // Add a new image selector
      $('<label class="post-image post-image-placeholder mrm mts empty">'
            +'<input type="file" class="photo_upload" id="Photofile_' + num_images + '" name="images_' + num_images + '[]" multiple />'
              +'<span class="icon-camera"><img src="https://cdn.onlinewebfonts.com/svg/img_134042.png"></span>'
              +'<p class="uppercase">Photo</p>'
            +'</label>').appendTo('.post-image-collection');
    }
    
    function handleFileSelect(evt) {
      var num_images = $("#imagenum").val();
      var $fileUpload = $("input#Photofile_" + num_images +"[type='file']");
      count = count + parseInt($fileUpload.get(0).files.length);
    
      if (parseInt($fileUpload.get(0).files.length) > 4 || count > 3) {
        alert("You can only upload a maximum of 3 photos");
        count = count - parseInt($fileUpload.get(0).files.length);
        evt.preventDefault();
        evt.stopPropagation();
        return false;
      }
      var files = evt.target.files;
      for (var i = 0, f; f = files[i]; i++) {
        if (!f.type.match('image.*')) {
          continue;
        }
        var reader = new FileReader();
    
        reader.onload = (function(theFile) {
          return function(e) {
            var span = document.createElement('span');
            span.innerHTML = ['<img class="thumb mrm mts" src="', e.target.result, '" title="', escape(theFile.name), '"/><span class="remove_img_preview"></span>'].join('');
            document.getElementById('list').insertBefore(span, null);
          };
        })(f);
    
        reader.readAsDataURL(f);
      }
    }
    
    // Apply the change event even for future inputs added dinamically (by JavaScript)
    $(document).change('.photo_upload', function(evt) {
      handleFileSelect(evt);
    });
    
    $('#list').on('click', '.remove_img_preview', function() {
      $(this).parent('span').remove();
    
      //this is not working...
      var i = array.indexOf($(this));
      if (i != -1) {
        array.splice(i, 1);
      }
      // tried this too:
      //$(this).parent('span').splice( 1, 1 );
    
      count--;
    });
    
    $(function() {
      // Add the first image selector
      addPhotoSelector();
    });
    form .post-image-collection {
      margin: -20px 0px 0px -20px;
      overflow: hidden;
    }
    
    form .post-image {
      position: relative;
      float: left;
      height: 152px;
      width: 170px;
      background: #f2f2f2;
      border: 1px dashed #ccc;
      padding: 0;
      border-radius: 4px;
      text-align: center;
      cursor: pointer;
    }
    
    .mrm {
      margin-right: 20px;
    }
    
    .mts {
      margin-top: 10px;
    }
    
    form .post-image img {
      max-width: 80px;
      max-height: 80px;
      width: auto;
      height: auto;
      vertical-align: top;
      border-radius: 3px;
      overflow: hidden;
    }
    
    form .post-image .icon-camera {
      display: none;
    }
    
    form .post-image input {
      position: absolute;
      z-index: 2;
      opacity: 0;
      width: 100%;
      height: 100%;
    }
    
    form .post-image.empty {
      position: relative;
      float: left;
      height: 130px;
      width: 130px;
      background: #f2f2f2;
      border: 1px dashed #ccc;
      padding: 0;
      border-radius: 4px;
      text-align: center;
      cursor: pointer;
      vertical-align: top;
    }
    
    form .post-image.empty .icon-camera {
      display: block;
      height: 30px;
      line-height: 30px;
      left: 40%;
      position: absolute;
      text-align: center;
      top: 50%;
      width: 30px;
      cursor: inherit;
      margin: -15px 0px 0px -15px;
    }
    
    form .post-image.empty .icon-camera img {
      height: 60px;
      width: 60px;
    }
    
    form .post-image.empty input {
      cursor: pointer;
    }
    
    form .post-image p,
    .file_container-orange p {
      margin: 10px 0;
      margin: 1rem 0;
      text-align: center;
      font-family: "OpenSansSemiBold", sans-serif;
    }
    
    .uppercase {
      text-transform: uppercase;
    }
    
    #list {
      float: left;
    }
    
    .thumb {
      height: 130px;
      width: 130px;
      margin-right: 20px;
      margin-top: 10px;
    }
    
    .remove_img_preview {
      position: relative;
      top: -46px;
      right: 40px;
      font-size: 20px;
      line-height: 1;
      padding: 4px 6px;
      background: white;
      border-radius: 0px 0px 0px 3px;
      text-align: center;
      cursor: pointer;
    }
    
    .remove_img_preview:before {
      content: "×";
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <form>
      <div class="row row-images">
        <label for="image">Images*</label>
        <div class="column image_container">
          <input type="hidden" id="imagenum" name="num_images" value="0" />
          <div class="post-image-collection">
            <label id="list"></label>
            <!-- The contents here will be filled by JavaScript -->
          </div>
        </div>
    </form>