76 lines
4.4 KiB
HTML
76 lines
4.4 KiB
HTML
<!doctype html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Styleguide – Pattern Datei-Upload</title>
|
||
<link rel="stylesheet" href="../styleguide.css">
|
||
</head>
|
||
<body>
|
||
<h1 class="sg-main-heading">Pattern – Datei-Upload</h1>
|
||
<section id="pattern-file-upload">
|
||
<p class="sg-preview-label">Pattern: Datei-Upload</p>
|
||
<form class="sg-file-upload" data-pattern="file-upload" action="#" method="post">
|
||
<div>
|
||
<label class="sg-label" for="file-upload-input">Dokumente hochladen</label>
|
||
<p class="sg-body sg-file-upload__description" id="file-upload-help">Mehrere Dateien auswählen. Erlaubte Formate: PDF, DOCX. Maximale Dateigröße: 10 MB pro Datei.</p>
|
||
</div>
|
||
<div class="sg-file-upload__dropzone" data-drag-over="false">
|
||
<input class="sg-file-input__control" id="file-upload-input" name="documents" type="file" multiple aria-describedby="file-upload-help file-upload-status">
|
||
<p class="sg-body sg-file-upload__prompt">Dateien hierher ziehen oder</p>
|
||
<button class="sg-interaction-element sg-button sg-button--active sg-file-upload__trigger" type="button">Dateien auswählen</button>
|
||
</div>
|
||
<p class="sg-body sg-file-upload__status" id="file-upload-status" aria-live="polite">Noch keine Dateien ausgewählt.</p>
|
||
<ul class="sg-file-upload__files" aria-label="Ausgewählte Dateien"></ul>
|
||
<button class="sg-interaction-element sg-button sg-button--process sg-button--process-inactive" type="submit" disabled aria-disabled="true">Hochladen</button>
|
||
</form>
|
||
</section>
|
||
<script>
|
||
(() => {
|
||
const upload = document.querySelector('[data-pattern="file-upload"]');
|
||
if (!upload) return;
|
||
const input = upload.querySelector('#file-upload-input');
|
||
const dropzone = upload.querySelector('.sg-file-upload__dropzone');
|
||
const trigger = upload.querySelector('.sg-file-upload__trigger');
|
||
const filesList = upload.querySelector('.sg-file-upload__files');
|
||
const status = upload.querySelector('.sg-file-upload__status');
|
||
const submit = upload.querySelector('[type="submit"]');
|
||
let selectedFiles = [];
|
||
const formatSize = (bytes) => bytes < 1024 * 1024 ? `${Math.max(1, Math.round(bytes / 1024))} KB` : `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
||
const render = () => {
|
||
filesList.innerHTML = '';
|
||
selectedFiles.forEach((file, index) => {
|
||
const item = document.createElement('li');
|
||
item.className = 'sg-file-upload__file';
|
||
const name = document.createElement('span');
|
||
name.className = 'sg-file-upload__file-name';
|
||
name.textContent = file.name;
|
||
const meta = document.createElement('span');
|
||
meta.className = 'sg-file-upload__file-meta';
|
||
meta.textContent = ` · ${formatSize(file.size)}`;
|
||
name.append(meta);
|
||
const remove = document.createElement('button');
|
||
remove.className = 'sg-interaction-element sg-button sg-button--active sg-file-upload__remove';
|
||
remove.type = 'button';
|
||
remove.textContent = 'Entfernen';
|
||
remove.addEventListener('click', () => { selectedFiles.splice(index, 1); render(); });
|
||
item.append(name, remove);
|
||
filesList.append(item);
|
||
});
|
||
const count = selectedFiles.length;
|
||
status.textContent = count === 0 ? 'Noch keine Dateien ausgewählt.' : `${count} Datei${count === 1 ? '' : 'en'} ausgewählt.`;
|
||
submit.disabled = count === 0;
|
||
submit.setAttribute('aria-disabled', String(count === 0));
|
||
submit.classList.toggle('sg-button--process-inactive', count === 0);
|
||
};
|
||
trigger.addEventListener('click', () => input.click());
|
||
input.addEventListener('change', () => { selectedFiles = [...selectedFiles, ...Array.from(input.files)]; input.value = ''; render(); });
|
||
['dragenter', 'dragover'].forEach((eventName) => dropzone.addEventListener(eventName, (event) => { event.preventDefault(); dropzone.dataset.dragOver = 'true'; }));
|
||
['dragleave', 'drop'].forEach((eventName) => dropzone.addEventListener(eventName, (event) => { event.preventDefault(); dropzone.dataset.dragOver = 'false'; }));
|
||
dropzone.addEventListener('drop', (event) => { selectedFiles = [...selectedFiles, ...Array.from(event.dataTransfer.files)]; render(); });
|
||
render();
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|