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

185 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
chrwahl 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>