0

I have a small HTML5 form where the user drops an image file, sees the preview, gets to know the dimensions of the image, fills an input element, and hits the button "Send" to dispatch it all (image and input text) through a POST request.

Problem is, the image data is not being sent together with the input data, even if the div and img elements have a name tag assigned to them. How can I accomplish that using the usual POST process?

Here is my code.

function removeDragData(e) {
  if (e.dataTransfer.items) { // Use DataTransferItemList interface to remove the drag data
    e.dataTransfer.items.clear();
  } else { // Use DataTransfer interface to remove the drag data
    e.dataTransfer.clearData();
  }
}
function formatBytes(a,b) {
  if (0 == a)
    return '0 Bytes';
  var c = 1024,
    d = b || 2,
    e = ['Bytes','KB','MB','GB','TB','PB','EB','ZB','YB'],
    f = Math.floor(Math.log(a)/Math.log(c));
  return parseFloat((a/Math.pow(c,f)).toFixed(d))+' '+e[f];
}
function getDim(img,tam) {
  var infoW = img.naturalWidth;
  var infoH = img.naturalHeight;
  var info = document.getElementById('addDadoInfo');
  info.innerHTML = 'Tamanho: ' + infoW + ' x ' + infoH + ' pixels (' + formatBytes(tam) + ')';
}
function drop(e,who) {
  e.preventDefault();  // Prevent default behavior (Prevent file from being opened)
  var i;
  if (e.dataTransfer.items) { // Use DataTransferItemList interface to access the file(s)
    for (i=0; i<e.dataTransfer.items.length; i++) {
      if (e.dataTransfer.items[i].kind === 'file') { // If dropped items aren't files, reject them
        var file = e.dataTransfer.items[i].getAsFile();
        if (file.type.indexOf('image/') == 0 && file.size <= 2*1024*1024) {
          // Process only the first image up to 2 MB
          var img = document.createElement('img');
          var tam = file.size;
          img.file = file;
          img.name = 'imgDImg';
          img.style.maxWidth = '400px';
          img.style.maxHeight = '300px';
          while (who.firstChild) {
            who.removeChild(who.firstChild); // removes the <p> element
          }
          who.appendChild(img);
          var reader = new FileReader();
          reader.onload = (function(aImg) {
            return function(ev) {
              aImg.src = ev.target.result;
              setTimeout(getDim,500,aImg,tam);
              };
            })(img);
          reader.readAsDataURL(file);
          break;
          //console.log('.A. file[' + i + '] = ' + file.name + '|' + file.type + '|' + file.size);
        }
      }
    }
  } else { // Use DataTransfer interface to access the file(s)
    for (i=0; i<e.dataTransfer.files.length; i++) {
      var file = e.dataTransfer.files[i];
      console.log('.B. file[' + i + '] = ' + file.name + '|' + file.type + '|' + file.size);
    }
  }
  removeDragData(e); // Pass event to removeDragData for cleanup
}
function dragOver(e) {
  e.preventDefault(); // Prevent default behavior (Prevent file from being opened)
}
.addDado {
  background-color:#DDD;
  width:400px;
  height:300px;
  text-align:center;
}
<form id='frmAddDado' autocomplete='on' method='post' action='index.php'>
  <div id='addDado1' name='addDado1' class='addDado' ondrop='drop(event,this)' ondragover='dragOver(event)'>
    <p>Drop image here.</p>
  </div>
  <div id='addDadoInfo'>(No data selected.)</div>
  <br>
  <label for='txaDRef'>Reference</label><br>
  <textarea id='txaDRef' name='txaDRef' cols=80 rows=5></textarea><br>
  <br>
  <input id='btnAddDado' type='submit' value='Add' disabled />
</form>
Rodrigo
  • 4,706
  • 6
  • 51
  • 94

1 Answers1

0

Well, this answer helped me to get it partially done, converting the image into base64 and attaching this to a hidden input. However, it's only 100% ok for PNG images. If the user tries to upload a JPG, there's no way it seems I can save the file as-is, i.e. without losing quality or increasing the file size.

So, I'm still looking for a better way to have both: thumbnail, dimensions and file size displayed and perfect file transfer.

EDIT

Digging more, I've found this answer, which does exactly what I needed!

A few modifications to the code above:

// in <form id='frmAddDado'>
<input id='fileIMG' name='fileIMG' type='file' style='display:none' />

// in function drop(e,who)
document.getElementById('fileIMG').files = e.dataTransfer.files;
Rodrigo
  • 4,706
  • 6
  • 51
  • 94