0

I've created an Image Uploader but it's not working properly. I'm not able to understand where am I going wrong. The JSFIDDLE of my image uploader is given below:

JSFIDDLE

The problem I am facing is when I click on choose files and select more than one files and open it, I wanted it to show the preview of all the images which I selected and it works properly but when I click on delete button it only deletes the preview that means if I submit the files even those files which I have deleted would be uploaded. On another hand I have to click Add more images button to create one more uploader same as above but when I add multiple images it does not show any preview so I cant even select or delete the images which I've selected by mistake. Can anyone find where am I going wrong. I need that add more images button too so that if we forget adding some images or the images are in different directory we can call one more input type files and that should function the same as previous.

Hardik Sisodia
  • 615
  • 3
  • 14
  • 37

2 Answers2

2

So, you were doing some odd things (like using a global variable with an integer assigned to it that I'm assuming you were using to keep track of your objects).

I've cleaned up what you had going on, and removed some redundant functions. Essentially, you needed to better utilize the JavaScript FileReader() function. You'll need to take a closer look at your buttons; as I didn't fix them for you. ;)

What you needed to do was iterate through your this.files array, and display the results using the FileReader() function. Code below.

    $('#add_more').click(function() {
      "use strict";
      $(this).before($("<div/>", {
        id: 'filediv'
      }).fadeIn('slow').append(
        $("<input/>", {
          name: 'file[]',
          type: 'file',
          id: 'file',
          multiple: 'multiple',
          accept: 'image/*'
        })
      ));
    });

    $('#upload').click(function(e) {
      "use strict";
      e.preventDefault();

      if (window.filesToUpload.length === 0 || typeof window.filesToUpload === "undefined") {
        alert("No files are selected.");
        return false;
      }

      // Now, upload the files below...
      // https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications#Handling_the_upload_process_for_a_file.2C_asynchronously
    });

    function deletePreview(ele, i) {
      "use strict";
      try {
        $(ele).parent().remove();
        window.filesToUpload.splice(i, 1);
      } catch (e) {
        console.log(e.message);
      }
    }

    $("#file").on('change', function() {
      "use strict";

      // create an empty array for the files to reside.
      window.filesToUpload = [];

      if (this.files.length >= 1) {
        $("[id^=previewImg]").remove();
        $.each(this.files, function(i, img) {
          var reader = new FileReader(),
            newElement = $("<div id='previewImg" + i + "' class='abcd'><img /></div>"),
            deleteBtn = $("<span class='delete' onClick='deletePreview(this, " + i + ")'>delete</span>").prependTo(newElement),
            preview = newElement.find("img");

          reader.onloadend = function() {
            preview.attr("src", reader.result);
            preview.attr("alt", img.name);
          };

          try {
            window.filesToUpload.push(document.getElementById("file").files[i]);
          } catch (e) {
            console.log(e.message);
          }

          if (img) {
            reader.readAsDataURL(img);
          } else {
            preview.src = "";
          }

          newElement.appendTo("#filediv");
        });
      }
    });
#formdiv {
  text-align: center;
}
#file {
  color: green;
  padding: 5px;
  border: 1px dashed #123456;
  background-color: #f9ffe5;
}
#img {
  width: 17px;
  border: none;
  height: 17px;
  margin-left: -20px;
  margin-bottom: 191px;
}
.upload {
  width: 100%;
  height: 30px;
}
.abcd {
  text-align: center;
  position: relative;
}
.abcd img {
  height: 200px;
  width: 200px;
  padding: 5px;
  border: 1px solid rgb(232, 222, 189);
}
.delete {
  color: red;
  font-weight: bold;
  position: absolute;
  top: 0;
  cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="formdiv">
  <div id="filediv">
    <input type="file" id="file" name="files[]" multiple="multiple" accept="image/*" title="Select Images To Be Uploaded">
    <br>
  </div>
  <input type="button" id="add_more" class="upload" value="Add More Images" />
  <input type="submit" name="submit" value="Add Product" class="upload" id="upload" title="Add Product To The Inventory">
</div>
kneeki
  • 2,444
  • 4
  • 17
  • 27
  • This works well. But there is another problem here, I created a delete button(Cross Icon) too which was shown on the image so that we can remove the image if selected by mistake but now its not showing there. – Hardik Sisodia May 12 '15 at 08:55
  • That shouldn't be terribly difficult to add. See how I added the `newElement = $("
    ")` area? Just below it, do the same thing, only create a "delete" cross icon. Then bind the onClick attribute to the ID of the newElement. Try it out. If you get stuck, let me know.
    – kneeki May 12 '15 at 15:40
  • I tried doing exactly what you said but then it stopped showing preview of images I select to upload and showed me the counts of images which are being uploaded and even the add more button stopped working after I insert a new variable for deleting image. – Hardik Sisodia May 13 '15 at 09:46
  • Added the delete button to my original answer. – kneeki May 13 '15 at 18:20
  • 1
    but this only deletes the preview if you see there even after you delete an image the count up there remains the same, that means only the preview gets deleted but when I submit the form it will upload the deleted image too right? – Hardik Sisodia May 16 '15 at 03:57
  • Right, this would only delete the preview. The filelist array is read only as far as I'm aware. Here's [another post](http://stackoverflow.com/questions/3144419/how-do-i-remove-a-file-from-the-filelist) on the subject. – kneeki May 16 '15 at 20:15
  • I saw the link provided by you but still I am not able to understand after we append delete button how can we delete the files from choose files, I tried various methods too but yet not successful in finishing this Image Uploader. I went too this [link](https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications) and saw **Handling the upload process for a file** but I think that too helps deleting the previews only but not the files from choose file section. – Hardik Sisodia May 18 '15 at 10:06
  • I've updated my snippet to include the removal of files from an array (`window.filesToUpload`). Essentially, since FileList is a read only array, you need to create a unique array which you have read/write privileges to. – kneeki May 18 '15 at 15:21
  • I tried your updated snippet but the problem is still the same images count ie. images don't get deleted from the choose files path but only from preview – Hardik Sisodia May 22 '15 at 16:08
  • any updates for the image uploader of mine I am still stuck here – Hardik Sisodia Jun 01 '15 at 11:56
  • Can you post a snippet (jsfiddle?) with the progress you've made so far? I'd be glad to help. – kneeki Jun 08 '15 at 14:42
  • This is the new updated [JsFiddle](https://jsfiddle.net/the_hardik_sisodia/gw64uxjj/7/) and then when I even tried making image uploader function for Add more button it doesn't come up with preview no clue why? Please do have a look at updated snippet I'm even updating snippet on the question I've had asked – Hardik Sisodia Jun 08 '15 at 17:55
  • As far as I understand, the `input type="file"` element is read-only. If you want to have a custom version, your safest and easiest bet would be using a library like [BootStrap FileStyle](http://markusslima.github.io/bootstrap-filestyle/). Using FileStyle alongside of the scripts I have already provided, you should be able to achieve exactly what you're looking for. – kneeki Jun 09 '15 at 00:58
  • Please check this updated **[JS Fiddle](http://jsfiddle.net/the_hardik_sisodia/gw64uxjj/9/)** I added the bootstrap script and added `$(":file").filestyle('clear');` as shown in the link provided by you in last comment but still it did not clear on image or particular images from the choose file button in fact it clears all the images but preview is still available. And the bootstrap changed my css as well for `input type="file"` how can i make it same because that looks beautiful and we can even drag and drop images in it properly.. – Hardik Sisodia Jun 09 '15 at 11:40
  • Ok, so I completely understand what you're looking for. That said, I'm not sure how to accomplish the feature to give a user the ability to edit the list of files /before/ uploading them without some serous hackery due to the restriction and security precaution of the read-only `input type='file'`. That said, here is a solution that I hope you'll be happy with: [jsFiddle](http://jsfiddle.net/gw64uxjj/12/) – kneeki Jun 09 '15 at 16:20
  • thats perfect just one problem which is what if I don't want to delete all the images together and remove only single image from 5 images, ie. If I uploaded 5 images together but then I find a wrong image which I might have inserted by mistake and I need to remove it not all so how cal I do that? – Hardik Sisodia Jun 09 '15 at 17:12
  • Deleting single image many is the only thing which is missing currently in this image uploader rest all is brilliant and very much happy for your support – Hardik Sisodia Jun 09 '15 at 17:23
  • No problem mate. If you ever figure out how to go about deleting a single image from the `FileList` do comment here so i can check it out. – kneeki Jun 09 '15 at 17:55
  • Do we need to create a delete icon or checkbox appending on preview image so that we can delete single or multiple image? Checkbox would work great I guess but i was wondering can we link that checkbox to a new clear button which will clear only selected one? – Hardik Sisodia Jun 09 '15 at 18:37
  • Read my comments above, afaik you cannot delete a single item. You may only delete all of the items. – kneeki Jun 09 '15 at 20:49
  • Any clue how can we upload the all 5 images names in mysql database but all should be uploaded in different columns of the same table?? For Example If there is already 5 columns created in a table viz: first_image_name, second_image_name, third_image_name, fourth_image_name, fifth_image_name & I select 3 images out of 5 and submit it so the names of Images from current Images Uploader should be stored in priority wise in different columns. Hope you got my point. – Hardik Sisodia Jun 11 '15 at 11:06
  • I didn't test this, but it should be more than enough to get you on to the right track. [pasteBin](http://pastebin.com/8pRUQPWx) – kneeki Jun 11 '15 at 14:58
  • Hey I tried inserting this [Image uploader](https://jsfiddle.net/gw64uxjj/12/) in [this form](https://jsfiddle.net/the_hardik_sisodia/6f5LLw2d/12/) in Images Row 2nd column where you can see old Image Uploader but due to bootstrap css my whole page gets messed and then even the preview is not shown there how can I insert that Image uploader in the form? Can You please check this where am I going wrong? This [JSFIDDLE](https://jsfiddle.net/the_hardik_sisodia/6f5LLw2d/16/) is new one with a new Image Uploader. Please do check I don't know where am I going wrong. – Hardik Sisodia Jun 14 '15 at 16:12
  • You were trying to load secure insecure (http) on a secure (https) page. I've fixed those issues. The preview doesn't work on the fiddle for some reason, but it works just fine if you make a .html page and run it. [JSFiddle](https://jsfiddle.net/6f5LLw2d/19/) – kneeki Jun 15 '15 at 17:05
  • I tried it but the output is still the same bootstrap css is disturbing my css file too and because of that the web design gets very messy. Is there another method to use bootstraps particular css style which applies only on the image uploader and not the whole page? – Hardik Sisodia Jun 16 '15 at 10:11
  • You need to go through each class that the FileStyle is using, and take just those styles from the bootstrap.css file, and add them to your specific CSS file. – kneeki Jun 17 '15 at 17:24
  • Is there some easy way out to just pick class which is needed for the image uploader from bootstrap css, because that bootstrap CSS is quite large mate and removing only that particular class from that CSS is way very lengthy process, I tried it but it comes up with a big mess at the end. – Hardik Sisodia Jun 22 '15 at 09:19
  • Go to their [customize section](http://getbootstrap.com/customize/), and disable everything you don't want? You should double check, but I think all you'd need is the Buttons module. – kneeki Jun 22 '15 at 14:38
  • I tried doing this too but still hr tags and alignments too get affected. – Hardik Sisodia Jun 25 '15 at 10:36
  • If you go through the css file (which is only the button components) from bootstrap and make sure only ".btn" classes are in there, it shouldn't affect anything else. – kneeki Jun 26 '15 at 14:01
  • I tried that too now but still my css is getting affected and not just that much I even tried clicking on clear button and that button comes up with some weird error too and I think it acts like a submit button later after I edit css totally confused.. When I use the website link provided by you to customize bootstrap and after selecting only .btn values and download it I get 4 files I tried all four css but still no success achieved mate. – Hardik Sisodia Jul 03 '15 at 18:29
  • If possible please do have a look at [this query](http://stackoverflow.com/q/31513715/4791856) – Hardik Sisodia Aug 27 '15 at 08:05
-1

This is my first time contributing to StackOverflow. I hope this helps someone. I am fairly new to web development. I would, however, be grateful if someone can turn the javascript code into a loop. The code below can easily upload multiple images to the server using their unique name="name";

function showPreviewOne(event){
    if(event.target.files.length > 0){
      let src = URL.createObjectURL(event.target.files[0]);
      let preview = document.getElementById("file-ip-1-preview");
      preview.src = src;
      preview.style.display = "block";
    } 
  }
  function myImgRemoveFunctionOne() {
      document.getElementById("file-ip-1-preview").src = "https://i.ibb.co/ZVFsg37/default.png";
    }
    /* **************************************************************************************** */

    function showPreviewTwo(event){
      if(event.target.files.length > 0){
        let src = URL.createObjectURL(event.target.files[0]);
        let preview = document.getElementById("file-ip-2-preview");
        preview.src = src;
        preview.style.display = "block";
      } 
    }
    function myImgRemoveFunctionTwo() {
        document.getElementById("file-ip-2-preview").src = "https://i.ibb.co/ZVFsg37/default.png";
      }
    /* **************************************************************************************************** */
    function showPreviewThree(event){
      if(event.target.files.length > 0){
        let src = URL.createObjectURL(event.target.files[0]);
        let preview = document.getElementById("file-ip-3-preview");
        preview.src = src;
        preview.style.display = "block";
      } 
    }
    function myImgRemoveFunctionThree() {
        document.getElementById("file-ip-3-preview").src = "https://i.ibb.co/ZVFsg37/default.png";
      }
    /* **************************************************************************************************** */
    function showPreviewFour(event){
      if(event.target.files.length > 0){
        let src = URL.createObjectURL(event.target.files[0]);
        let preview = document.getElementById("file-ip-4-preview");
        preview.src = src;
        preview.style.display = "block";
      } 
    }
    function myImgRemoveFunctionFour() {
        document.getElementById("file-ip-4-preview").src = "https://i.ibb.co/ZVFsg37/default.png";
      }
      /* **************************************************************************************** */
  
      function showPreviewFive(event){
        if(event.target.files.length > 0){
          let src = URL.createObjectURL(event.target.files[0]);
          let preview = document.getElementById("file-ip-5-preview");
          preview.src = src;
          preview.style.display = "block";
        } 
      }
      function myImgRemoveFunctionFive() {
          document.getElementById("file-ip-5-preview").src = "https://i.ibb.co/ZVFsg37/default.png";
        }
      /* **************************************************************************************************** */
      function showPreviewSix(event){
        if(event.target.files.length > 0){
          let src = URL.createObjectURL(event.target.files[0]);
          let preview = document.getElementById("file-ip-6-preview");
          preview.src = src;
          preview.style.display = "block";
        } 
      }
      function myImgRemoveFunctionSix() {
          document.getElementById("file-ip-6-preview").src = "https://i.ibb.co/ZVFsg37/default.png";
        }
      /* **************************************************************************************************** */
  body {
    margin:0px;
    padding:0px;
    background:#f1f1f1;
  }
 .image-upload-one{
    grid-area: img-u-one;
    display: flex;
    justify-content: center;
  }
  .image-upload-two{
    grid-area: img-u-two;
    display: flex;
    justify-content: center;
  }
  .image-upload-three{
    grid-area: img-u-three;
    display: flex;
    justify-content: center;
  }
  .image-upload-four{
    grid-area: img-u-four;
    display: flex;
    justify-content: center;
  }
  .image-upload-five{
    grid-area: img-u-five;
    display: flex;
    justify-content: center;
  }
  .image-upload-six{
    grid-area: img-u-six;
    display: flex;
    justify-content: center;
  }

  .image-upload-container{
    display: grid;
    grid-template-areas: 'img-u-one img-u-two img-u-three img-u-four img-u-five img-u-six';
  }
  .center {
    display:inline;
    margin: 3px;
  }

  .form-input {
    width:100px;
    padding:3px;
    background:#fff;
    border:2px dashed dodgerblue;
  }
  .form-input input {
    display:none;
  }
  .form-input label {
    display:block;
    width:100px;
    height: auto;
    max-height: 100px;
    background:#333;
    border-radius:10px;
    cursor:pointer;
  }
  
  .form-input img {
    width:100px;
    height: 100px;
    margin: 2px;
    opacity: .4;
  }

  .imgRemove{
    position: relative;
    bottom: 114px;
    left: 68%;
    background-color: transparent;
    border: none;
    font-size: 30px;
    outline: none;
  }
  .imgRemove::after{
    content: ' \21BA';
    color: #fff;
    font-weight: 900;
    border-radius: 8px;
    cursor: pointer;
  }

  .small{
    color: firebrick;
    font-size:15px;
  }

  @media only screen and (max-width: 700px){
    .image-upload-container{
      grid-template-areas: 'img-u-one img-u-two img-u-three'
       'img-u-four img-u-five img-u-six';
    }
  }
 <div class="image-upload-container">
      <div class="image-upload-one">
        <div class="center">
          <div class="form-input">
            <label for="file-ip-1">
              <img id="file-ip-1-preview" src="https://i.ibb.co/ZVFsg37/default.png">
              <button type="button" class="imgRemove" onclick="myImgRemoveFunctionOne()"></button>
            </label>
            <input type="file"  name="img_one" id="file-ip-1" accept="image/*" onchange="showPreviewOne(event);">
          </div>
          <small class="small">Use the &#8634; icon to reset the image</small>
        </div>
      </div>
      <!-- ************************************************************************************************************ -->
      <div class="image-upload-two">
        <div class="center">
          <div class="form-input">
            <label for="file-ip-2">
              <img id="file-ip-2-preview" src="https://i.ibb.co/ZVFsg37/default.png">
              <button type="button" class="imgRemove" onclick="myImgRemoveFunctionTwo()"></button>
            </label>
            <input type="file" name="img_two" id="file-ip-2" accept="image/*" onchange="showPreviewTwo(event);">
          </div>
          <small class="small">Use the &#8634; icon to reset the image</small>
        </div>
      </div>

      <!-- ************************************************************************************************************ -->
      <div class="image-upload-three">
        <div class="center">
          <div class="form-input">
            <label for="file-ip-3">
              <img id="file-ip-3-preview" src="https://i.ibb.co/ZVFsg37/default.png">
              <button type="button" class="imgRemove" onclick="myImgRemoveFunctionThree()"></button>
            </label>
            <input type="file" name="img_three" id="file-ip-3" accept="image/*" onchange="showPreviewThree(event);">
          </div>
          <small class="small">Use the &#8634; icon to reset the image</small>
        </div>
      </div>
      <!-- *********************************************************************************************************** -->
        <div class="image-upload-four">
          <div class="center">
            <div class="form-input">
              <label for="file-ip-4">
                <img id="file-ip-4-preview" src="https://i.ibb.co/ZVFsg37/default.png">
                <button type="button" class="imgRemove" onclick="myImgRemoveFunctionFour()"></button>
              </label>
              <input type="file" name="img_four" id="file-ip-4" accept="image/*" onchange="showPreviewFour(event);">
            </div>
            <small class="small">Use the &#8634; icon to reset the image</small>
          </div>
        </div>
        <!-- ************************************************************************************************************ -->
        <div class="image-upload-five">
          <div class="center">
            <div class="form-input">
              <label for="file-ip-5">
                <img id="file-ip-5-preview" src="https://i.ibb.co/ZVFsg37/default.png">
                <button type="button" class="imgRemove" onclick="myImgRemoveFunctionFive()"></button>
              </label>
              <input type="file" name="img_five" id="file-ip-5" accept="image/*" onchange="showPreviewFive(event);">
            </div>
            <small class="small">Use the &#8634; icon to reset the image</small>
          </div>
        </div>
  
        <!-- ************************************************************************************************************ -->
        <div class="image-upload-six">
          <div class="center">
            <div class="form-input">
              <label for="file-ip-6">
                <img id="file-ip-6-preview" src="https://i.ibb.co/ZVFsg37/default.png">
                <button type="button" class="imgRemove" onclick="myImgRemoveFunctionSix()"></button>
              </label>
              <input type="file" name="img_six" id="file-ip-6" accept="image/*" onchange="showPreviewSix(event);">
            </div>
            <small class="small">Use the &#8634; icon to reset the image</small>
          </div>
        </div>

      <!-- ************************************************************************************************************** -->
    </div>
    
  • Please don’t ask a question in response to someone else’s question. Start a new question. Thanks. Good luck. – Hoppo Jun 12 '20 at 02:33