Is it possible to drag and drop an image from an <img> tag into the input of an html form?

174 Views Asked by At

enter image description hereI'm creating a demo page for an image stitching tool, where the user's can use images shown on the webpage instead of uploading their own.

I want the user to be able to drag the image from the img tag to the input within the form.

Here is the html that I have so far:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Image Stitcher</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
    <script src="static/js/index.js" defer></script>
</head>

<body>
    <div class="content">
        <nav>
            <h1>Image Stitcher</h1>
            <a class="link" href="{{url_for('home')}}">home</a>
            <a class="link right" href="{{url_for('about')}}">about</a>
        </nav>
        <br />
        <br />

        <div class="row">
            <div class="form-area">
                <form action="http://127.0.0.1:5000" method="POST" enctype="multipart/form-data">
                    <label for="left_image">Upload the left image:</label>
                    <input type="file" id="left_image" name="left_image" accept="image/png, image/jpeg" />
                    <br />
                    <label for="right_image">Upload the right image:</label>
                    <input type="file" id="right_image" name="right_image" accept="image/png, image/jpeg" />
                    <br />
                    <button class="submit" type="submit">Start Stitching</button>
                </form>
            </div>
            <div class="image-row">
                <div class="demo-image">
                    <p> drag me to the <strong>left image</strong></p>
                    <img id="image-to-drag" src="/static/left_art.png" alt="Left Image">
                </div>
                <div class="demo-image">
                    <p> drag me to the <strong>right image</strong></p>
                    <img src="/static/right_art.png" alt="Right Image">
                </div>
            </div>
        </div>
    </div>
    <br />
    <br />
</body>

</html>

I'm also open to answers where the ui fakes this behaviour, and uploads some base64 encoding of the image instead.

I have tried using the drag event, but the DragEvent.dataTransfer.files comes up empty when I drag the image.

// from index.js
function drag(event) {
    console.log('DRAG')
    console.log(event)
}

// and change the img elements to this
<img ondragstart="drag(event)" draggable="true" src="/static/right_art.png" alt="Right Image">
1

There are 1 best solutions below

0
On

If the image is already on the web server (or another web server) you can just grab the URL of the image and add that to the form.

document.querySelector('.image-row').addEventListener('dragstart', e => {
  e.dataTransfer.setData("text/plain", e.target.src);
});

document.querySelector('.form-area').addEventListener('dragover', e => {
  e.preventDefault();
  let formarea = e.target.closest('.form-area');
  formarea.querySelectorAll('.image').forEach(elm => elm.classList.remove('over'));
  let div = e.target.closest('.image');
  if (div) div.classList.add('over');
  e.dataTransfer.dropEffect = "copy";
});

document.querySelector('.form-area').addEventListener('drop', e => {
  e.preventDefault();
  let src = e.dataTransfer.getData("text/plain");
  let div = e.target.closest('.image');
  if (div) {
    let img = div.querySelector('img');
    img.src = src;
    document.forms.form01[`${img.dataset.position}_image`].value = src;
  }
});
.row {
  display: flex;
}

.image-row {
  display: flex;
  gap: 2px;
}

form {
  display: flex;
  flex-direction: column;
}

.image {
  width: 100px;
  height: 150px;
  border: dashed silver 2px;
}

.image.over {
  border: dashed navy 2px;
}

.demo-image {
  width: 100px;
}
<div class="row">
  <div class="form-area">
    <form name="form01" action="/" method="POST" enctype="multipart/form-data">
      <label>Upload the left image:</label>
      <div class="image">
        <img data-position="left" />
      </div>
      <input type="hidden" name="left_image" />
      <label>Upload the right image:</label>
      <div class="image">
        <img data-position="right" />
      </div>
      <input type="hidden" name="right_image" />
      <button class="submit" type="submit">Start Stitching</button>
    </form>
  </div>
  <div class="image-row">
    <div class="demo-image">
      <p> drag me to the <strong>left image</strong></p>
      <img src="https://placehold.co/100x150/orange/white" alt="Left Image" draggable="true">
    </div>
    <div class="demo-image">
      <p> drag me to the <strong>right image</strong></p>
      <img src="https://placehold.co/100x150/tomato/white" alt="Right Image" draggable="true">
    </div>
  </div>
</div>