nulled
nulled

Reputation: 413

Selecting multiple images but storing the data in separate places using Javascript

So I am using the following code for users to upload photos (as you can see I am not allowing the user to select multiple files all at once, they will have to select one file, open it, then select the next file, open it etc).

HTML:

<input type="file" capture="camera" accept="image/*" id="files1" name="files[]">
<output id="list"></output>

<form action="post.php">
<input type='hidden' id='imgsrc1' name='imgsrc1'>
<input type='hidden' id='filepath1' name='filepath1'>

<input type='hidden' id='imgsrc2' name='imgsrc2'>
<input type='hidden' id='filepath2' name='filepath2'>

<input type='hidden' id='imgsrc3' name='imgsrc3'>
<input type='hidden' id='filepath3' name='filepath3'>

<input type="submit" name="submit" value"Submit Listing">
</form>

JavaScript

function handleFileSelect(evt) {
var files = evt.target.files; // FileList object

// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {

  // Only process image files.
  if (!f.type.match('image.*')) {
    continue;
  }

  var reader = new FileReader();

  // Closure to capture the file information.
  reader.onload = (function(theFile) {
    return function(e) {
      // Render thumbnail.
      var span = document.createElement('span');
      imgsrc = e.target.result;
      filename = theFile.name;
      filepath = "images/uploads/" + theFile.name;
      span.innerHTML = ['<img class="thumb" src="', imgsrc,
                        '" title="', filepath, '"/>'].join('');
      document.getElementById('list').insertBefore(span, null);
      document.getElementById('filepath1').value=filepath;
      document.getElementById('imgsrc1').value=imgsrc;

    };
  })(f);

  // Read in the image file as a data URL.
  reader.readAsDataURL(f);

 }
}

document.getElementById('files1').addEventListener('change', handleFileSelect, false);

The user selects the first image, the JavaScript then displays the photo by adding it inside <output id="list"></output>

The lines below (taken from the code above) store the selected image's path into input box 'filepath1' and the base64 image data into input box 'imgsrc1':

JavaScript:

  document.getElementById('filepath1').value=filepath;
  document.getElementById('imgsrc1').value=imgsrc;

HTML:

 <input type='hidden' id='imgsrc1' name='imgsrc1'>
 <input type='hidden' id='filepath1' name='filepath1'>

The problem is, I want the user to be able to select 3 images, one by one. When the user selects the first image it is fine, but when they select the second image it is going to run that JavaScript function again and overwrite/add to anything stored in the hidden input boxes.

When the user selects a second image, I want the data to be stored in two different hidden input boxes, for example:

<input type='hidden' id='imgsrc2' name='imgsrc2'>
<input type='hidden' id='filepath2' name='filepath2'>

I have no idea how to do this. There is probably a really easy way to do this by using a counter or something but it's currently 11:18PM and I have the client in at 8am tomorrow, this is the last bit I need to fix for them lol. Any help would be appreciated.

Upvotes: 2

Views: 1364

Answers (2)

Nachshon Schwartz
Nachshon Schwartz

Reputation: 15765

Add a counter and simply increment it each time you add an image:

var imgNum = 0;

function handleFileSelect(evt) {

if (imgNum > 3) return;
var files = evt.target.files; // FileList object

// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {

  // Only process image files.
  if (!f.type.match('image.*')) {
    continue;
  }

  var reader = new FileReader();

  // Closure to capture the file information.
  reader.onload = (function(theFile) {
    return function(e) {
      // Render thumbnail.
      var span = document.createElement('span');
      imgsrc = e.target.result;
      filename = theFile.name;
      filepath = "images/uploads/" + theFile.name;
      span.innerHTML = ['<img class="thumb" src="', imgsrc,
                        '" title="', filepath, '"/>'].join('');
      document.getElementById('list').insertBefore(span, null);
      document.getElementById('filepath'+imgNum).value=filepath;
      document.getElementById('imgsrc'+imgNum).value=imgsrc;

    };
  })(f);

  // Read in the image file as a data URL.
  reader.readAsDataURL(f);

 }
  imgNum++;
}

document.getElementById('files1').addEventListener('change', handleFileSelect, false);

Upvotes: 1

Matt Styles
Matt Styles

Reputation: 2452

If I get what you want then a naive solution would be to use your naming convention and the index of your for loop:

for ( let i = 1; i <= 3; i++ ) {
  f = files[ i - 1 ]
  // ...
  document.getElementById( 'filepath' + i ).whatever
}

Having said that I would probably go about this differently, I'd append the event listener and simply push new files on to an array, if the array hits its maximum length (in this case, 3) then do some logic that stops the user from uploading more and then send the data however you like without using the <form> and hidden elements.

Upvotes: 1

Related Questions