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. ?
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:
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!