VERO/templates/uploadForm.php
2026-03-04 10:12:09 +01:00

424 lines
16 KiB
PHP
Executable File

<!-- Upload Section -->
<div class="upload">
<div class="text-container status-success">
<div>Bitte erst alle Dateien zum Upload auswählen (Eingabe für weitere Uploads über "+"-Button auswählen) und dann final den Button "Dateien hochladen" klicken.
<p>
Bei Korrekturen bitte alle Dateien erneut hochladen. Bereits hochgeladene Dateien werden überschrieben.
</p>
</div>
</div>
<form id="uploadForm" method="POST" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="10000000" />
<div class="mt-3" id="uploadItems">
<div class="input-group col-12">
<div class="col-6 ps-2" >
<input type="file" lang="de" name="pdf_file_1" class="form-control" accept=".pdf" required>
</div>
<div class="col-2 ps-3 me-3">
<select name="doc_type_1" class="form-select" required>
<option value="">-- bitte wählen --</option>
<option value="publikation">Publikation</option>
<option value="anhang">Anhang</option>
<option value="notennachweis">Notennachweis</option>
<option value="weiterernachweis">Weitere Nachweise</option>
</select>
</div>
<button class="btn button_fix" type="button" id="button-add-upload-1" onclick="addUploadItem()"> <i class="bi h3 bi-file-plus"></i></button>
</div>
</div>
<!-- <div class="add-remove-container">
<!-- <button type="button" class="add-btn" onclick="addUploadItem()">+ Weitere Datei hinzufügen</button> -->
<!-- <button type="button" class="remove-btn" onclick="removeUploadItem()">- Letzte Datei entfernen</button>
</div>
-->
<!-- Progress Bar -->
<div class="progress-container" id="progressContainer">
<div class="progress-bar">
<div class="progress-fill" id="progressFill"></div>
</div>
<div class="progress-text" id="progressText">0%</div>
</div>
<!-- Status Messages -->
<div class="status-message" id="statusMessage"></div>
</div>
<div class="submit-container d-grid pe-5 d-md-flex justify-content-md-end">
<button id="submitBtn" type="submit" class="btn btn-success">Dateien hochladen</button>
</div>
</form>
<!-- Upload Results -->
<div id="uploadResults" style="display: none;">
<h4>Ergebnisse des Dateiuploads:</h4>
<div class="file-list" id="fileList"></div>
</div>
</form>
</div>
<script>
let fileCount = 1;
const maxFiles = 10;
function addUploadItem() {
if (fileCount >= maxFiles) {
alert('Maximal 10 Dateien können hochgeladen werden.');
return;
}
// +-Buttons der vorherigen Felder ausblenden
var c = fileCount;
var a = "button-add-upload-" + c;
// sonst geht das Plus-Zeichen auf dem ersten Feld verloren!
if (c > 1) {
document.getElementById(a).style.display = 'none';
}
fileCount++;
const uploadItems = document.getElementById('uploadItems');
const newItem = document.createElement('div');
newItem.className = 'input-group col-12';
newItem.innerHTML = `
<div class="col-6 pt-2 ps-2">
<input type="file" lang="de" name="pdf_file_${fileCount}" class="form-control" accept=".pdf">
</div>
<div class="col-2 pt-2 ps-3 me-3">
<select name="doc_type_${fileCount}" class="form-select">
<option value="">-- bitte wählen --</option>
<option value="publikation">Publikation</option>
<option value="anhang">Anhang</option>
<option value="notennachweis">Notennachweis</option>
<option value="weiterernachweis">Weitere Nachweise</option>
</select>
</div>
<button class="pt-2 btn button_fix" type="button" id="button-add-upload-${fileCount}" onclick="addUploadItem()"> <i class="bi h3 bi-file-plus"></i></button>`;
if (fileCount > 1) {
newItem.innerHTML += `
<button class="pt-2 btn button_fix" type="button" id="button-delete-upload-${fileCount}" onclick="removeUploadItem()"> <i class="bi h3 bi-file-minus"> </button>`;
}
newItem.innerHTML += `
</div>
`;
uploadItems.appendChild(newItem);
}
function removeUploadItem() {
if (fileCount <= 1) {
alert('Mindestens eine Datei muss vorhanden sein.');
return;
}
var c = fileCount - 1;
var a = "button-add-upload-" + c;
document.getElementById(a).style.display = 'block';
const uploadItems = document.getElementById('uploadItems');
uploadItems.removeChild(uploadItems.lastElementChild);
fileCount--;
}
document.getElementById('uploadForm').addEventListener('submit', function(e) {
e.preventDefault();
if (validateForm()) {
uploadFilesAjax();
}
});
function validateForm() {
// Validierung: Prüfen ob für jede ausgewählte Datei auch eine Dokumentenart gewählt wurde
const currentDiv = document.getElementById('uploadForm'); // oder deine andere Methode
const fileInputs = currentDiv.querySelectorAll('input[type="file"]');
const selectInputs = currentDiv.querySelectorAll('select');
console.log(selectInputs);
let isValid = true;
let hasAtLeastOneFile = false;
let hasAtLeastOnePublicationFile = false;
// Vorherige Fehlermeldungen löschen
hideStatusMessage();
// Check if type of at least one of the uploaded files has value "publication"
for (let i = 0; i < fileInputs.length; i++) {
const selectInput = selectInputs[i];
if (selectInput.value == 'publikation') {
hasAtLeastOnePublicationFile = true;
break;
}
}
if (hasAtLeastOnePublicationFile === false) {
hideStatusMessage();
showStatusMessage(`Mindestens eine hochgeladene Datei muss vom Typ "Publikation" sein.`, `error`);
return false;
}
for (let i = 0; i < fileInputs.length; i++) {
const fileInput = fileInputs[i];
const selectInput = selectInputs[i];
if (fileInput.files.length > 0) {
hasAtLeastOneFile = true;
if (!selectInput.value) {
hideStatusMessage();
showStatusMessage(`Bitte wählen Sie eine Dokumentenart für Datei ${i + 1} aus.`, `error`);
// alert(`Bitte wählen Sie eine Dokumentenart für Datei ${i + 1} aus.`);
isValid = false;
break;
}
}
if (!hasAtLeastOneFile) {
hideStatusMessage();
showStatusMessage(`Bitte wählen Sie mindestens eine Datei zum Hochladen aus.`, `error`);
//alert('Bitte wählen Sie mindestens eine Datei zum Hochladen aus.');
isValid = false;
break;
}
// Prüfe Dateigröße (10MB)
const maxSize = 10 * 1024 * 1024;
if (fileInput.files[0].size > maxSize) {
showStatusMessage(`Datei ${i + 1} ist zu groß (max. 10MB).`, 'error');
isValid = false;
break;
}
// Prüfe Dateityp
if (fileInput.files[0].type !== 'application/pdf') {
showStatusMessage(`Datei ${i + 1} ist kein gültiges PDF.`, 'error');
isValid = false;
break;
}
return isValid;
}
}
function uploadFilesAjax() {
const form = document.getElementById('uploadForm');
const formData = new FormData(form);
const submitBtn = document.getElementById('submitBtn');
const progressContainer = document.getElementById('progressContainer');
const progressFill = document.getElementById('progressFill');
const progressText = document.getElementById('progressText');
// UI für Upload-Start vorbereiten
submitBtn.disabled = true;
submitBtn.textContent = 'Upload läuft...';
progressContainer.style.display = 'block';
hideStatusMessage();
document.getElementById('uploadResults').style.display = 'none';
// XMLHttpRequest für Progress-Tracking
const xhr = new XMLHttpRequest();
// Progress Event
xhr.upload.addEventListener('progress', function(e) {
if (e.lengthComputable) {
const percentComplete = Math.round((e.loaded / e.total) * 100);
progressFill.style.width = percentComplete + '%';
progressText.textContent = percentComplete + '% - ' + formatFileSize(e.loaded) + ' von ' + formatFileSize(e.total);
}
});
// Load Event (Upload abgeschlossen)
xhr.addEventListener('load', function() {
if (xhr.status === 200) {
try {
const response = JSON.parse(xhr.responseText);
handleUploadResponse(response);
} catch (e) {
showStatusMessage('Fehler beim Verarbeiten der Server-Antwort.', 'error');
console.error('JSON Parse Error:', e);
}
} else {
showStatusMessage(`Server-Fehler: ${xhr.status} ${xhr.statusText}`, 'error');
}
resetUploadUI();
});
// Error Event
xhr.addEventListener('error', function() {
showStatusMessage('Upload fehlgeschlagen. Bitte prüfen Sie Ihre Internetverbindung.', 'error');
resetUploadUI();
});
// Timeout Event
xhr.addEventListener('timeout', function() {
showStatusMessage('Upload-Timeout. Bitte versuchen Sie es erneut.', 'error');
resetUploadUI();
});
// Upload starten
xhr.open('POST', 'templates/upload.php');
xhr.timeout = 300000; // 5 Minuten Timeout
xhr.send(formData);
}
function handleUploadResponse(response) {
if (response.success) {
showStatusMessage(response.message, 'success');
displayUploadResults(response.files);
// Formular zurücksetzen nach erfolgreichen Upload
setTimeout(() => {
document.getElementById('uploadForm').reset();
// Alle bis auf das erste Upload-Feld entfernen
const uploadItems = document.getElementById('uploadItems');
while (uploadItems.children.length > 1) {
uploadItems.removeChild(uploadItems.lastElementChild);
fileCount--;
}
}, 2000);
} else {
let errorMessage = response.message;
if (response.errors && response.errors.length > 0) {
errorMessage += '\n\nFehler:\n' + response.errors.join('\n');
}
showStatusMessage(errorMessage, 'error');
// Zeige auch erfolgreich hochgeladene Dateien an
if (response.uploaded_files && response.uploaded_files.length > 0) {
displayUploadResults(response.uploaded_files);
}
}
}
function displayUploadResults(files) {
const resultsDiv = document.getElementById('uploadResults');
const fileList = document.getElementById('fileList');
fileList.innerHTML = '';
var c = 0;
files.forEach(function(file, index) {
const documentTypeName = file.document_type;
console.log('Datei:', file.original_name, 'Typ:', documentTypeName); // Debug-Ausgabe
const fileItem = document.createElement('div');
fileItem.className = 'file-item';
let hiddenFields = '';
// Hidden fields nur bei Publikationen hinzufügen
if (file.document_type === 'publikation') {
hiddenFields = `
<input type="hidden"
name="publicatedDocument"
id="publicatedDocument"
value="${file.original_name}"
required>
<input type="hidden"
name="publicatedDocumentType"
id="publicatedDocumentType"
value="${file.document_type}"
required>
`;
// console.log("Hidden Fields in Upload: " +hiddenFields);
}
fileItem.innerHTML = `
<div id="uploadItem${c}" style="font-weight:bold;">${file.original_name}<br></div>
Typ: ${getDocumentTypeName(file.document_type)}<br>
Größe: ${formatFileSize(file.size)}<br>
${hiddenFields}
<div id="uploadHiddenType${c}" style="display:none;">${getDocumentTypeName(file.document_type)}</div>
<div id="uploadHiddenItem${c}" style="display:none;">${file.saved_name}</div>
`;
fileList.appendChild(fileItem);
c++;
});
resultsDiv.style.display = 'block';
}
function getDocumentTypeName(type) {
const types = {
'publikation': 'Publikation',
'anhang': 'Anhang',
'notennachweis': 'Notennachweis',
'weiterernachweis': 'Weitere Nachweise'
};
return types[type] || type;
}
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
function showStatusMessage(message, type) {
const statusDiv = document.getElementById('statusMessage');
statusDiv.textContent = message;
statusDiv.className = 'status-message status-' + type;
statusDiv.style.display = 'block';
}
function hideStatusMessage() {
const statusDiv = document.getElementById('statusMessage');
statusDiv.style.display = 'none';
}
function resetUploadUI() {
const submitBtn = document.getElementById('submitBtn');
const progressContainer = document.getElementById('progressContainer');
const progressFill = document.getElementById('progressFill');
const progressText = document.getElementById('progressText');
submitBtn.disabled = false;
submitBtn.textContent = 'Dateien hochladen';
// Progress bar nach kurzer Verzögerung ausblenden
setTimeout(() => {
progressContainer.style.display = 'none';
progressFill.style.width = '0%';
progressText.textContent = '0%';
}, 1000);
}
// Alternative: Upload mit fetch() (moderne Browser)
/* function uploadFilesWithFetch() {
const form = document.getElementById('uploadForm');
const formData = new FormData(form);
fetch('upload.php', {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
handleUploadResponse(data);
})
.catch(error => {
console.error('Upload error:', error);
showStatusMessage('Upload fehlgeschlagen: ' + error.message, 'error');
})
.finally(() => {
resetUploadUI();
});
}
*/
</script>