79 lines
2.1 KiB
TypeScript
79 lines
2.1 KiB
TypeScript
import { ApplicationController } from './application_controller';
|
|
export class FileInputResetController extends ApplicationController {
|
|
static targets = ['fileList'];
|
|
declare fileListTarget: HTMLElement;
|
|
|
|
connect() {
|
|
super.connect();
|
|
this.updateFileList();
|
|
this.element.addEventListener('change', (event) => {
|
|
if (
|
|
event.target instanceof HTMLInputElement &&
|
|
event.target.type === 'file'
|
|
) {
|
|
this.updateFileList();
|
|
}
|
|
});
|
|
}
|
|
|
|
updateFileList() {
|
|
const files = this.fileInput?.files ?? [];
|
|
this.fileListTarget.innerHTML = '';
|
|
|
|
const deleteLabel =
|
|
this.element.getAttribute('data-delete-label') || 'Delete';
|
|
|
|
Array.from(files).forEach((file, index) => {
|
|
const container = document.createElement('li');
|
|
container.classList.add('flex', 'flex-gap-2', 'fr-mb-1w');
|
|
|
|
const deleteButton = this.createDeleteButton(deleteLabel, index);
|
|
container.appendChild(deleteButton);
|
|
|
|
const listItem = document.createElement('div');
|
|
listItem.textContent = file.name;
|
|
|
|
container.appendChild(listItem);
|
|
this.fileListTarget.appendChild(container);
|
|
});
|
|
}
|
|
|
|
createDeleteButton(deleteLabel: string, index: number) {
|
|
const button = document.createElement('button');
|
|
button.textContent = deleteLabel;
|
|
button.classList.add(
|
|
'fr-btn',
|
|
'fr-btn--tertiary',
|
|
'fr-btn--sm',
|
|
'fr-icon-delete-line'
|
|
);
|
|
|
|
button.addEventListener('click', (event) => {
|
|
event.preventDefault();
|
|
this.removeFile(index);
|
|
});
|
|
|
|
return button;
|
|
}
|
|
|
|
removeFile(index: number) {
|
|
const files = this.fileInput?.files;
|
|
if (!files) return;
|
|
|
|
const dataTransfer = new DataTransfer();
|
|
Array.from(files).forEach((file, i) => {
|
|
if (index !== i) {
|
|
dataTransfer.items.add(file);
|
|
}
|
|
});
|
|
|
|
if (this.fileInput) this.fileInput.files = dataTransfer.files;
|
|
this.updateFileList();
|
|
}
|
|
|
|
private get fileInput(): HTMLInputElement | null {
|
|
return this.element.querySelector(
|
|
'input[type="file"]'
|
|
) as HTMLInputElement | null;
|
|
}
|
|
}
|