I have this file field:
<div data-controller="file-upload">
<%= file_field_tag "revision_photos[photo][]",
name: "revision_photos[photo][]",
class: "w-full",
id: "photo_#{index}",
disabled: !is_checked,
data: {
rules_form_target: "photo",
file_upload_target: "file",
action: "file-upload#fileChanged change->file-upload#fileChanged change->resize-image#resizeImage",
controller: "resize-image"
},
accept: "image/*",
capture: "environment" %>
<label for="photo_#{index}" class="cursor-pointer">
<span data-file-upload-target="filename" class="text-gray-500">No hay archivo seleccionado</span>
</label>
</div>
it has two stimulus controllers, the one giving me problems is the controller to resize a image in client side:
// app/javascript/controllers/resize_image_controller.js
import { Controller } from "@hotwired/stimulus"
export default class ResizeImageController extends Controller {
static targets = ["file"];
resizeImage(event) {
const input = event.target;
if (!input.files.length) return;
const file = input.files[0];
if (!file.type.startsWith('image/')) return;
const reader = new FileReader();
reader.onload = (e) => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const maxWidth = 400;
const scaleFactor = maxWidth / img.width;
canvas.width = maxWidth;
canvas.height = img.height * scaleFactor;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
canvas.toBlob((blob) => {
const newFile = new File([blob], file.name, {
type: file.type,
lastModified: Date.now()
});
const dataTransfer = new DataTransfer();
dataTransfer.items.add(newFile);
input.files = dataTransfer.files;
// Trigger any existing change handlers after updating the file input
input.dispatchEvent(new Event('change', { bubbles: true }));
}, file.type);
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
}
}
When I still didn’t have that controller it worked fine, if I uploaded a second file the first one was overwritten, so the field showed the name of the second file and it was the one uploaded.
But after adding the controller, now when I add a second file, the field starts to show both files intermittently, and the file that uploaded is just by luck.
¿How can I fix it so it works as before? I can’t remove the controller and doing the resize in backend, since I need to keep the data submited as light as possible.
I tried using the line input.value = "";
before the new DataTransfer, but it didn’t work