Home  >  Article  >  Web Front-end  >  Drag & Drop Images with Preview using Stimulus Outlets

Drag & Drop Images with Preview using Stimulus Outlets

Susan Sarandon
Susan SarandonOriginal
2024-09-27 06:22:03151browse

Drag & Drop Images with Preview using Stimulus Outlets

This articles was originally published on Rails Designer


In a previous article I explored a way to preview images before upload with Stimulus.

I know want to extend its functionality by adding a drag & drop. Along the way I am also using Stimulus outlets to tie the two functionalities together. Showcasing more advanced use of small Stimulus controllers.

I assume you walked through all the steps of the previous mentioned article.

Let's start with the HTML. It's using the other HTML with just a few attributes added.

<div data-controller="image-preview dropzone" data-action="dragover->dropzone#dragOver dragleave->dropzone#dragLeave drop->dropzone#drop">
  <img data-image-preview-target="canvas" hidden class="object-cover size-48">

  <input type="file" accept="image/*" data-image-preview-target="source" data-dropzone-target="input" data-action="image-preview#show" hidden>
</div>

Let's create the dropzone_controller.js.

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static targets = ["input"];

  dragOver(event) {
    event.preventDefault();
  }

  dragLeave(event) {
    event.preventDefault();
  }

  drop(event) {
    event.preventDefault();

    this.#updateInputField(event.dataTransfer.files[0]);
  }
}

All these methods do is preventing the default event when these actions are invoked. The drop() function also calls the private function this.#updateInputField(). Let's add it.

export default class extends Controller {
  // …

  // private
  #updateInputField(file) {
    const dataTransfer = new DataTransfer();

    dataTransfer.items.add(file);

    this.inputTarget.files = dataTransfer.files;
  }
  // …
}

This will inject the dropped image into the inputTarget field. And just like that you can drag and drop images onto the element. ?

Preview images with outlets

An important part is missing though… the image isn't show which looks like a bug. Luckily with the image_preview_controller.js already done. This is a simple exercise.

First tweak the HTML by adding the following attributes:

<div data-controller="image-preview dropzone" data-dropzone-image-preview-outlet="#image-preview" data-action="dragover->dropzone#dragOver dragleave->dropzone#dragLeave drop->dropzone#drop" id="image-preview>
  <img data-image-preview-target="canvas" hidden class="object-cover size-48">

  <input type="file" accept="image/*" data-image-preview-target="source" data-dropzone-target="input" data-action="image-preview#show" hidden>
</div>

Added:

  • data-dropzone-image-preview-outlet="#image-preview";
  • id="image-preview".

Now two lines are needed in the dropzone_controller.js.

export default class extends Controller {
  static outlets = ["image-preview"];
  // …

  drop(event) {
    // …

    this.imagePreviewOutlet.show();

    // …
  }

  // …
}

Now when you drop an image it fires the show() function on the image_preview_controller.js. ?

I like to use small Stimulus controllers like these that work great together.


Rails Designer has this Stimulus controller packaged with a few extras added. Get your copy today.

The above is the detailed content of Drag & Drop Images with Preview using Stimulus Outlets. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn