2557 lines
83 KiB
JavaScript
2557 lines
83 KiB
JavaScript
//
|
|
// Javascripts für VERO
|
|
//
|
|
// Roland Keck (2025)
|
|
//
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
hide("author",2,9);
|
|
hide("abstract",2,3);
|
|
hide("identificator",2,5);
|
|
hide("subject",2,10);
|
|
// hide("divCreativeCommons",1,1);
|
|
// hide("cc0commercial",1,1);
|
|
// hide("cc0share", 1, 1);
|
|
hide("publisherInEditedVolume",2,9);
|
|
hideElement("divErstveroeffentlichungOpenAccess");
|
|
hideElement("divErstveroeffentlichungUrheberrecht");
|
|
hideElement("divZweitveroeffentlichungOpenAccess");
|
|
hideElement("Select4A4B");
|
|
hideElement("divZweitUrh4A");
|
|
hideElement("divErstUrh");
|
|
hideElement("divZweitUrh4B");
|
|
hideElement("divCommon");
|
|
hideElement("erstVeroeffentlichtSection");
|
|
hideElement("mitteilungSection");
|
|
|
|
} )
|
|
|
|
function hide(FieldName, start, end)
|
|
{
|
|
for (let i = start; i <= end; i++) {
|
|
hideElement(FieldName + i);
|
|
// document.getElementById(FieldName + i).style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function hideElement(ele) {
|
|
|
|
var present = document.getElementById(ele);
|
|
|
|
if (present) {
|
|
present.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function showElement(ele) {
|
|
|
|
var present = document.getElementById(ele);
|
|
|
|
if (present) {
|
|
present.style.display = 'block';
|
|
}
|
|
}
|
|
|
|
|
|
function insert(FieldName,pos,max)
|
|
{
|
|
|
|
let a = pos -1
|
|
let ret = false
|
|
|
|
switch(FieldName) {
|
|
case 'author':
|
|
if (a > 1) {
|
|
// special case: first author is not an input!!
|
|
ret = validateNameFormat(FieldName, a);
|
|
if (ret === false) return;
|
|
}
|
|
break;
|
|
case 'publisherInEditedVolume':
|
|
ret = validateEmptyEntry(FieldName, a);
|
|
if (ret === false) return;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
document.getElementById(FieldName + pos).style.display = 'block';
|
|
if (pos < max) { document.getElementById("button-add-" + FieldName +'-' + pos).style.display = 'block';}
|
|
document.getElementById("button-del-" + FieldName +'-' + pos).style.display = 'block';
|
|
document.getElementById("button-add-" + FieldName +'-' + (pos-1)).style.display = 'none';
|
|
}
|
|
|
|
function del(FieldName,pos,min)
|
|
{
|
|
|
|
switch(FieldName) {
|
|
case 'author':
|
|
if (pos > 1) {
|
|
// special case: first author is not an input!!
|
|
deleteErrorMessage(FieldName, pos);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
document.getElementById(FieldName + pos).style.display = 'none';
|
|
if (pos > min) { document.getElementById("button-del-" + FieldName +'-' + pos).style.display = 'none';}
|
|
document.getElementById("button-add-" + FieldName +'-' + (pos-1)).style.display = 'block';
|
|
return;
|
|
}
|
|
|
|
function checkcontent(FieldName)
|
|
{
|
|
// alert(FieldName)
|
|
var value = document.getElementById(FieldName).value ;
|
|
// alert (FieldName +": " +value);
|
|
}
|
|
|
|
function showInputBibliografic()
|
|
{
|
|
document.getElementById('title').style.display = 'block';
|
|
hide("author",2,5);
|
|
document.getElementById('authors').style.display = 'block';
|
|
|
|
}
|
|
|
|
function hideInputBibliografic()
|
|
{
|
|
document.getElementById('title').style.display = 'none';
|
|
document.getElementById('authors').style.display = 'none';
|
|
|
|
}
|
|
|
|
function oldcheckBoxType(checkedField) {
|
|
document.getElementById("checkBoxType").style.display = 'none';
|
|
/* var fields = document.getElementById("checkBoxType").getElementsByTagName('label');
|
|
for(var i = 0; i < fields.length; i++) {
|
|
alert (fields[i]);
|
|
fields[i].disabled = true;
|
|
}
|
|
*/
|
|
// activate part of the input reference in "checkedField"
|
|
const typeFields = [];
|
|
// typeFields.push("Monografie", "Sammelbandbeitrag", "Zeitschriftenartikel", "Qualifizierungsarbeit", "DiscussionPaper","Konferenzbeitrag");
|
|
typeFields.push("Monografie", "Sammelbandbeitrag", "Zeitschriftenartikel", "Qualifikationsarbeit");
|
|
|
|
for (let i = 0; i < typeFields.length; i++) {
|
|
document.getElementById('div' + typeFields[i]).style.display = 'none';
|
|
const form = document.getElementById('div' + typeFields[i]);
|
|
resetFormFields('div' + typeFields[i]);
|
|
}
|
|
document.getElementById('div' + checkedField).style.display = 'block';
|
|
|
|
}
|
|
|
|
|
|
function resetFormFields(divToClear) {
|
|
|
|
const div = document.getElementById(divToClear);
|
|
const inputs = div.querySelectorAll('input, textarea, select');
|
|
|
|
inputs.forEach(field => {
|
|
if (field.type === 'checkbox' || field.type === 'radio') {
|
|
field.checked = false;
|
|
} else if (field.tagName === 'SELECT') {
|
|
field.selectedIndex = 0;
|
|
} else {
|
|
field.value = '';
|
|
}
|
|
});
|
|
}
|
|
|
|
function showErrors() {
|
|
|
|
// Prüfen, ob Pflichtfelder gefüllt sind
|
|
emptyFields = validateRequiredFields() ;
|
|
|
|
let errorArray = [];
|
|
let warningArray = [];
|
|
let message = '';
|
|
let errorclass = '';
|
|
|
|
for (let i = 0; i < emptyFields.length; i++) {
|
|
switch (emptyFields[i]) {
|
|
case "titleinput1" : message = "Titelangabe fehlt."; errorclass = "error"; break;
|
|
case "abstractinput1" : message = "Bitte mindestens ein Abstract eingeben."; errorclass = "error"; break;
|
|
case "publicationyearinput1":
|
|
message = "Bitte Erscheinungsjahr in den bibliografischen Grunddaten eingeben"; errorclass = "error"; break;
|
|
case "publicatedDocument"
|
|
: message = "Kein PDF-Dokument hochgeladen."; errorclass = "error"; break;
|
|
case "publicatedDocumentType"
|
|
: message = "Bitte prüfen Sie, ob mindestens ein Dokument mit der Eigenschaft 'Publikation' hochgeladen wurde."; errorclass = "error"; break;
|
|
case "publishedInEditedVolumeinput1":
|
|
message = "Bei Sammelbandbeitrag: bitte Titel des Sammelbands ergänzen."; errorclass= "warning"; break;
|
|
case "publishedInJournalinput1":
|
|
message = "Bei Zeitschriftenartikel: bitte Titel der Zeitschrift ergänzen, in der der Artikel erschienen ist."; errorclass= "warning"; break;
|
|
case "qualificationType_select1" :
|
|
message = "Bei Qualifikationsarbeit: bitte Art der Qualifikationsarbeit angeben"; errorclass= "warning"; break;
|
|
case "qualifiedInstitutioninput1":
|
|
message = "Bei Qualifikationsarbeit: bitte Name der titelverleihenden Institution angeben"; errorclass= "warning"; break;
|
|
case "qualifiedYearinput1" :
|
|
message = "Bei Qualifikationsarbeit: bitte Jahr angeben"; errorclass= "warning"; break;
|
|
case "pageQualification1" :
|
|
message = "Bei Qualifikationsarbeit: bitte Seitenanzahl angeben"; errorclass= "warning"; break;
|
|
default: continue;
|
|
}
|
|
if (errorclass =="error") {
|
|
errorArray.push({
|
|
message: message,
|
|
errorclass: errorclass
|
|
});
|
|
} else {
|
|
warningArray.push({
|
|
message: message,
|
|
errorclass: errorclass
|
|
});
|
|
}
|
|
|
|
}
|
|
if (errorArray.length == 0) {
|
|
showSummary() ;
|
|
return;
|
|
}
|
|
|
|
|
|
console.log(errorArray);
|
|
|
|
var modal = document.getElementById('arrayModal');
|
|
|
|
// Direkter CSS-Zugriff ohne !important
|
|
if (modal) {
|
|
modal.style.display = 'block';
|
|
modal.style.visibility = 'visible';
|
|
modal.style.position = 'fixed';
|
|
modal.style.zIndex = '99999';
|
|
modal.style.left = '0px';
|
|
modal.style.top = '0px';
|
|
modal.style.width = '100%';
|
|
modal.style.height = '100%';
|
|
modal.style.backgroundColor = 'rgba(0,0,0,0.5)';
|
|
}
|
|
|
|
// FormData erstellen
|
|
var formData = new FormData();
|
|
formData.append('errorArray', JSON.stringify(errorArray));
|
|
formData.append('warningArray', JSON.stringify(warningArray));
|
|
$('#arrayModal').modal('show');
|
|
$('#modalBody').html('Loading...');
|
|
|
|
// AJAX-Aufruf
|
|
setTimeout(function() {
|
|
$.ajax({
|
|
url: 'showSummaryErrors.php',
|
|
method: 'POST',
|
|
data: formData,
|
|
processData: false,
|
|
contentType: false,
|
|
success: function(html) {
|
|
$('#modalBody').html(html); // IN Modal laden!
|
|
},
|
|
error: function(xhr, status, error) {
|
|
$('#modalBody').html('Fehler: ' + error);
|
|
$('#arrayModal').modal('show');
|
|
}
|
|
});
|
|
}, 100); //100 ms Verzögerung
|
|
|
|
return;
|
|
// alert ("Nicht alle Pflichtfelder ausgefüllt. Bitte korrigieren.");
|
|
}
|
|
|
|
|
|
|
|
function showSummary() {
|
|
|
|
var modal = document.getElementById('arrayModal');
|
|
|
|
// Direkter CSS-Zugriff ohne !important
|
|
if (modal) {
|
|
modal.style.display = 'block';
|
|
modal.style.visibility = 'visible';
|
|
modal.style.position = 'fixed';
|
|
modal.style.zIndex = '99999';
|
|
modal.style.left = '0px';
|
|
modal.style.top = '0px';
|
|
modal.style.width = '100%';
|
|
modal.style.height = '100%';
|
|
modal.style.backgroundColor = 'rgba(0,0,0,0.5)';
|
|
}
|
|
|
|
const relevantDivs = [ "BibliographicData", "IdentificatorData", "TypeData", "SubjectData", "contractData", "uploadData" ];
|
|
|
|
// Globale Arrays für die Daten
|
|
let bibliographicDataArray = [];
|
|
let identificatorDataArray = [];
|
|
let typeDataArray = [];
|
|
let subjectDataArray = [];
|
|
let contractDataArray = [];
|
|
let uploadDataArray = [];
|
|
|
|
// BibliographicData auslesen
|
|
bibliographicDataArray = readDataFromDiv('BibliographicData');
|
|
|
|
// IdentificatorData auslesen
|
|
identificatorDataArray = readDataFromDiv('IdentificatorData');
|
|
|
|
// TypeData auslesen
|
|
typeDataArray = readDataFromDiv('TypeData');
|
|
|
|
//SubjectData auselesen
|
|
subjectDataArray = readDataFromDiv('SubjectData');
|
|
|
|
//contractData auslesen
|
|
contractDataArray = readDataFromDiv('contractData');
|
|
|
|
//uploadData auslesen
|
|
uploadDataArray = readDataFromUploadDiv('fileList');
|
|
|
|
//Console ausgeben
|
|
//console.log('BibliographicData Array:', bibliographicDataArray);
|
|
//console.log('IdentificatorData Array:', identificatorDataArray);
|
|
//console.log('TypeData Array:', typeDataArray);
|
|
//console.log('SubjectData Array:', subjectDataArray);
|
|
//console.log('ContractData Array:', contractDataArray);
|
|
//console.log('UploadData Array:', uploadDataArray);
|
|
|
|
// FormData erstellen
|
|
var formData = new FormData();
|
|
formData.append('bibliographicArray', JSON.stringify(bibliographicDataArray));
|
|
formData.append('identificatorArray', JSON.stringify(identificatorDataArray));
|
|
formData.append('typeArray', JSON.stringify(typeDataArray));
|
|
formData.append('subjectArray', JSON.stringify(subjectDataArray));
|
|
formData.append('contractArray', JSON.stringify(contractDataArray));
|
|
formData.append('uploadArray', JSON.stringify(uploadDataArray));
|
|
|
|
$('#arrayModal').modal('show');
|
|
$('#modalBody').html('Loading...');
|
|
|
|
// AJAX-Aufruf
|
|
setTimeout(function() {
|
|
$.ajax({
|
|
url: 'checkModal.php',
|
|
method: 'POST',
|
|
data: formData,
|
|
processData: false,
|
|
contentType: false,
|
|
success: function(html) {
|
|
$('#modalBody').html(html); // IN Modal laden!
|
|
},
|
|
error: function(xhr, status, error) {
|
|
$('#modalBody').html('Fehler: ' + error);
|
|
$('#arrayModal').modal('show');
|
|
}
|
|
});
|
|
}, 100); //100 ms Verzögerung
|
|
|
|
return;
|
|
}
|
|
|
|
function closeModal() {
|
|
|
|
$('#arrayModal').hide();
|
|
|
|
// Backdrop explizit entfernen
|
|
$('.modal-backdrop').remove();
|
|
$('body').removeClass('modal-open');
|
|
$('body').css('overflow', 'auto'); // Scroll wieder aktivieren
|
|
|
|
}
|
|
|
|
// ✅ correctData mit komplettem Reset
|
|
function correctData() {
|
|
closeModal();
|
|
// Optional: Button-Funktion nach Schließen testen
|
|
setTimeout(() => {
|
|
console.log('Modal geschlossen - Button sollte funktionieren');
|
|
}, 100);
|
|
|
|
}
|
|
|
|
function finishPublication() {
|
|
closeModal();
|
|
}
|
|
|
|
|
|
// Funktion: Daten aus einem spezifischen Div auslesen
|
|
|
|
function readDataFromUploadDiv(divId) {
|
|
let dataArray = [];
|
|
const fieldArray = ["uploadItem", "uploadHiddenType", "uploadHiddenItem"];
|
|
|
|
// Div finden
|
|
const div = document.getElementById(divId);
|
|
if (!div) {
|
|
console.warn('Div mit ID "' + divId + '" nicht gefunden!');
|
|
return dataArray;
|
|
}
|
|
|
|
var numberOfChildren = div.children.length
|
|
|
|
|
|
// Spezielle Felder im Div durchlaufen
|
|
for(let i = 0; i < numberOfChildren ; i++) {
|
|
const uploadItem = document.getElementById("uploadItem" +i).textContent;
|
|
// const uploadHiddenType = document.getElementById("uploadHiddenType" +i).textContent;
|
|
const uploadHiddenItem = document.getElementById("uploadHiddenItem" +i).textContent;
|
|
const uploadHiddenType = document.getElementById("uploadHiddenType" +i).textContent;
|
|
|
|
// Nur Felder mit Werten berücksichtigen
|
|
if (uploadItem && uploadItem.trim() !== '') {
|
|
dataArray.push({
|
|
fieldId: "uploadItem" +i,
|
|
fieldValue: uploadItem.trim()
|
|
});
|
|
}
|
|
|
|
if(uploadHiddenType && uploadHiddenType.trim() != '') {
|
|
dataArray.push({
|
|
fieldId: "uploadType" +i ,
|
|
fieldValue: uploadHiddenType.trim()
|
|
});
|
|
}
|
|
|
|
if(uploadHiddenItem && uploadHiddenItem.trim() != '') {
|
|
dataArray.push({
|
|
fieldId: "uploadHiddenItem" +i ,
|
|
fieldValue: uploadHiddenItem.trim()
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
return dataArray;
|
|
}
|
|
|
|
|
|
// Funktion: Daten aus einem spezifischen Div auslesen
|
|
function readDataFromDiv(divId) {
|
|
|
|
|
|
let dataArray = [];
|
|
|
|
// Div finden
|
|
const $div = $('#' +divId);
|
|
|
|
if ($div.length === 0) {
|
|
console.warn('Div mit ID "' + divId + '" nicht gefunden!');
|
|
return dataArray;
|
|
}
|
|
|
|
// Alle Eingabefelder im Div durchlaufen
|
|
$div.find('input, select, textarea').each(function() {
|
|
const $field = $(this);
|
|
const fieldId = $field.attr('id');
|
|
const fieldType = $field.prop('tagName').toLowerCase();
|
|
const inputType = $field.attr('type') || 'text';
|
|
let fieldValue = $field.val();
|
|
let isSelected = false;
|
|
|
|
// Sicherstellen, dass fieldValue ein String ist
|
|
if (fieldValue === null || fieldValue === undefined) {
|
|
fieldValue = ''
|
|
} else {
|
|
fieldValue = String(fieldValue);
|
|
}
|
|
|
|
// Spezielle Behandlung für verschiedene Feldtypen
|
|
if (inputType === 'checkbox') {
|
|
// Checkbox: Nur hinzufügen wenn gechecked
|
|
isSelected = $field.is(':checked');
|
|
fieldValue = isSelected ? ($field.val() || 'checked') : '';
|
|
|
|
} else if (inputType === 'radio') {
|
|
// Radio: Nur hinzufügen wenn selected
|
|
isSelected = $field.is(':checked');
|
|
fieldValue = isSelected ? $field.val() : '';
|
|
|
|
} else if (fieldType === 'select') {
|
|
// Select: Prüfen ob etwas ausgewählt wurde (nicht der leere default-Wert)
|
|
isSelected = (fieldValue !== '' && fieldValue !== null);
|
|
|
|
} else {
|
|
// Input/Textarea: Standard-Behandlung
|
|
isSelected = (fieldValue.trim() !== '');
|
|
}
|
|
|
|
// Nur Felder mit Namen und Werten berücksichtigen
|
|
if (fieldId && isSelected && fieldValue && fieldValue.trim() !== '') {
|
|
|
|
// Daten zum Array hinzufügen
|
|
dataArray.push({
|
|
fieldId: fieldId,
|
|
fieldValue: fieldValue.trim(),
|
|
fieldType: $field.prop('tagName').toLowerCase(),
|
|
fieldId: $field.prop('id').toLowerCase(),
|
|
inputType: $field.attr('type') || 'text',
|
|
isSelected: isSelected
|
|
});
|
|
}
|
|
});
|
|
|
|
return dataArray;
|
|
}
|
|
|
|
function oldcheckMultiPublish() {
|
|
|
|
const publishTypeSelection = document.querySelector('input[name="publishType"]:checked');
|
|
const licenseTypeSelection = document.querySelector('input[name="licenseType"]:checked');
|
|
|
|
if (! publishTypeSelection || !licenseTypeSelection) {
|
|
return
|
|
}
|
|
|
|
hideElement("divErstveroeffentlichungOpenAccess");
|
|
hideElement("divErstveroeffentlichungUrheberrecht");
|
|
hideElement("divZweitveroeffentlichungOpenAccess");
|
|
hideElement("Select4A4B");
|
|
hideElement("divZweitUrh4A");
|
|
hideElement("divErstUrh");
|
|
hideElement("divZweitUrh4B");
|
|
hideElement("divCommon");
|
|
hideElement("erstVeroeffentlichtSection");
|
|
hideElement("mitteilungSection");
|
|
|
|
if (publishTypeSelection.value == 'Erstveröffentlichung' && licenseTypeSelection.value == 'CC-Lizenz') {
|
|
showElement("divErstveroeffentlichungOpenAccess");
|
|
showElement("divCommon");
|
|
showElement("mitteilungSection");
|
|
}
|
|
|
|
if (publishTypeSelection.value == 'Erstveröffentlichung' && licenseTypeSelection.value == 'Deutschem Urheberrecht') {
|
|
showElement("divErstUrh");
|
|
showElement("divCommon");
|
|
showElement("mitteilungSection");
|
|
}
|
|
|
|
if (publishTypeSelection.value == 'Zweitveröffentlichung' && licenseTypeSelection.value == 'CC-Lizenz') {
|
|
showElement("divZweitveroeffentlichungOpenAccess");
|
|
showElement("divCommon");
|
|
showElement("erstVeroeffentlichtSection");
|
|
showElement("mitteilungSection");
|
|
}
|
|
|
|
if (publishTypeSelection.value == 'Zweitveröffentlichung' && licenseTypeSelection.value == 'Deutschem Urheberrecht') {
|
|
showElement("Select4A4B");
|
|
|
|
// showElement("divZweitveroeffentlichungUrheberrecht4B");
|
|
}
|
|
}
|
|
|
|
|
|
function showNextStep(Version) {
|
|
|
|
hideElement("divZweitUrh4A");
|
|
hideElement("divZweitUrh4B");
|
|
showElement("erstVeroeffentlichtSection");
|
|
showElement("mitteilungSection");
|
|
|
|
if (Version == "Version4B") {
|
|
showElement("divZweitUrh4B");
|
|
showElement("divCommon");
|
|
|
|
} else {
|
|
showElement("divZweitUrh4A");
|
|
showElement("divCommon");
|
|
}
|
|
|
|
}
|
|
|
|
function checkLicense(checkedField) {
|
|
|
|
// alert (checkedField)
|
|
|
|
document.getElementById('divCreativeCommons1').style.display = 'block';
|
|
//document.getElementById('cc0share1').style.display = 'block';
|
|
//document.getElementById('cc0commercial1').style.display = 'block';
|
|
document.getElementById('licenseType').style.display = 'none';
|
|
}
|
|
|
|
|
|
|
|
function clearTypeData() {
|
|
|
|
document.getElementById("checkBoxType").style.display = 'block';
|
|
const typeFields = [];
|
|
//typeFields.push("Monografie", "Sammelbandbeitrag", "Zeitschriftenartikel", "Qualifizierungsarbeit", "DiscussionPaper","Konferenzbeitrag");
|
|
typeFields.push("Monografie", "Sammelbandbeitrag", "Zeitschriftenartikel", "Qualifikationsarbeit", "Konferenzbeitrag");
|
|
for (let i = 0; i < typeFields.length; i++) {
|
|
document.getElementById('div' + typeFields[i]).style.display = 'none';
|
|
// document.getElementById('div' + typeFields[i]).innerHTML = "";
|
|
}
|
|
}
|
|
|
|
function saveBibliographicData() {
|
|
// TODO store bibliografic data on server
|
|
|
|
/* titleinput1
|
|
authorinput1 - authorinput9
|
|
role_select1 - role_select9
|
|
publicationyearinput1
|
|
abstract_language_select1 - abstract_language_select3
|
|
abstractinput1 - abstractinput3
|
|
*/
|
|
return;
|
|
|
|
}
|
|
|
|
function saveSubjectData() {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
function saveIdentificators() {
|
|
|
|
/* identificator_select1 - identificator_select5
|
|
identificator1 - identificator5
|
|
*/
|
|
return
|
|
|
|
}
|
|
|
|
function saveTypeData() {
|
|
/*
|
|
|
|
Zeitschriftenartikel: publishedInJournal1, publishedInVolume1, pagefromArticle1, pagetoArticle1, reviewArticle1
|
|
Sammelbandbeitrag: publishedInEditedVolume1, publisherInEditedVolume1, pagefromEditedVolume1, pagetoEditedVolume1, review_editedvolume_select1
|
|
DiscussionPaper: pages1
|
|
Monografie: publisher1, pagesMonograph1
|
|
Konferenzbeitrag: publishedInEditedVolume1, conferenceName1, conferenceDetail1
|
|
Qualifizierungsarbeit: qualifiedInstitution1, qualifiedFachbereich1, qualifiedPerson1, qualifiedNote1, pagesQualification1
|
|
|
|
|
|
|
|
|
|
*/
|
|
return
|
|
|
|
}
|
|
|
|
function saveMultiPublish() {
|
|
|
|
return
|
|
}
|
|
|
|
|
|
|
|
function showHelp(field)
|
|
{
|
|
|
|
switch(field) {
|
|
case 'helpFirstTitles': var r = '<div class="modal" tabindex="-1"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Modal title</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <p>Modal body text goes here.</p> </div> </div></div></div>'
|
|
alert (r);
|
|
break;
|
|
|
|
case 'helpFirstTitle': var r = "<h5>Hinweis zur Erfassung von AutorInnen</h5>Bitte AutorInnen in der Form 'Nachname, Vorname' eingeben";
|
|
break;
|
|
default:
|
|
}
|
|
document.getElementById(field).innerHTML = r;
|
|
document.getElementById(field).style.visibility = "block";
|
|
}
|
|
|
|
function delHelp(field) {
|
|
|
|
var hf= 'help' + field;
|
|
var f = 'input' + field;
|
|
|
|
document.getElementById(f).blur();
|
|
document.getElementById(hf).style.visibility = "hidden";
|
|
}
|
|
|
|
// Javascripts für den Honeypot
|
|
//
|
|
|
|
// JavaScript für erweiterte Bot-Erkennung
|
|
|
|
/*document.getElementById('js_enabled').value = '1';
|
|
|
|
let interactions = 0;
|
|
let mouseMoved = false;
|
|
|
|
// Zähle Formular-Interaktionen
|
|
document.querySelectorAll('input, textarea').forEach(function(field) {
|
|
field.addEventListener('focus', function() {
|
|
interactions++;
|
|
document.getElementById('form_interactions').value = interactions;
|
|
});
|
|
});
|
|
|
|
// Maus-Bewegung tracken
|
|
document.addEventListener('mousemove', function() {
|
|
if (!mouseMoved) {
|
|
mouseMoved = true;
|
|
document.getElementById('mouse_moved').value = '1';
|
|
}
|
|
});
|
|
*/
|
|
|
|
|
|
|
|
// Formular-Validierung (findet in den einzelnen PHP-Dateien direkt statt)
|
|
/* document.getElementById('contactForm').addEventListener('submit', function(e) {
|
|
var name = document.getElementById('name').value.trim();
|
|
var email = document.getElementById('email').value.trim();
|
|
var message = document.getElementById('message').value.trim();
|
|
|
|
if (!name || !email || !message) {
|
|
e.preventDefault();
|
|
alert('Bitte füllen Sie alle Felder aus.');
|
|
}
|
|
});
|
|
*/
|
|
|
|
|
|
// Bootstrap 5 Validierung
|
|
/* (function() {
|
|
'use strict';
|
|
window.addEventListener('load', function() {
|
|
var forms = document.getElementsByClassName('needs-validation');
|
|
var validation = Array.prototype.filter.call(forms, function(form) {
|
|
form.addEventListener('onmouseout', function(event) {
|
|
if (form.checkValidity() === false) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
}
|
|
form.classList.add('was-validated');
|
|
}, false);
|
|
});
|
|
}, false);
|
|
})();
|
|
|
|
// Formular Submit Handler
|
|
document.getElementById('validationForm').addEventListener('onmouseout', function(e) {
|
|
e.preventDefault();
|
|
// Bootstrap Validierung hinzufügen
|
|
this.classList.add('was-validated');
|
|
|
|
// Prüfen ob alle Felder gültig sind
|
|
if (this.checkValidity()) {
|
|
alert('Formular erfolgreich validiert!');
|
|
// Hier würden Sie normalerweise die Daten senden
|
|
}
|
|
});
|
|
*/
|
|
|
|
// Manuelle Validierung für Custom Field
|
|
function validateField(inputField, fieldNumber) {
|
|
var field = document.getElementById(inputField + 'input' + fieldNumber);
|
|
var error = document.getElementById(inputField + fieldNumber + 'Error');
|
|
var success = document.getElementById(inputField + fieldNumber + 'Success');
|
|
var value = field.value.trim();
|
|
|
|
if (value.length === 0) {
|
|
// Leer - keine Anzeige
|
|
field.classList.remove('is-valid', 'is-invalid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'none';
|
|
} else if (value.length < 3) {
|
|
// Ungültig
|
|
field.classList.remove('is-valid');
|
|
field.classList.add('is-invalid');
|
|
error.style.display = 'block';
|
|
success.style.display = 'none';
|
|
} else {
|
|
// Gültig
|
|
field.classList.remove('is-invalid');
|
|
field.classList.add('is-valid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'block';
|
|
}
|
|
}
|
|
|
|
|
|
function validateAlpha(inputField, fieldNumber) {
|
|
|
|
const alphanumeric = /^[\p{sc=Latn}\p{Nd}0-9 .,-:\/]*$/u;
|
|
|
|
var field = document.getElementById(inputField + 'input' + fieldNumber);
|
|
var error = document.getElementById(inputField + fieldNumber + 'Error');
|
|
var success = document.getElementById(inputField + fieldNumber + 'Success');
|
|
var value = field.value.trim();
|
|
|
|
// Validate alphanumeric
|
|
|
|
if (value.match(alphanumeric)) {
|
|
// Valid
|
|
field.classList.remove('is-invalid');
|
|
field.classList.add('is-valid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'block';
|
|
} else {
|
|
field.classList.remove('is-valid');
|
|
field.classList.add('is-invalid');
|
|
error.style.display = 'block';
|
|
success.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
|
|
function validateDigits(inputField, fieldNumber) {
|
|
|
|
const digits = /^[\p{sc=Latn}\p{Nd}0-9]*$/u;
|
|
|
|
var field = document.getElementById(inputField + 'input' + fieldNumber);
|
|
var error = document.getElementById(inputField + fieldNumber + 'Error');
|
|
var success = document.getElementById(inputField + fieldNumber + 'Success');
|
|
var value = field.value.trim();
|
|
|
|
// Validate digits
|
|
|
|
if (value.match(digits)) {
|
|
// Valid
|
|
field.classList.remove('is-invalid');
|
|
field.classList.add('is-valid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'block';
|
|
} else {
|
|
field.classList.remove('is-valid');
|
|
field.classList.add('is-invalid');
|
|
error.style.display = 'block';
|
|
success.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function validatePages(inputField, fieldNumber) {
|
|
|
|
const pages = /^(Seite|S\.)?[0-9\-\.\s]+$/
|
|
|
|
var field = document.getElementById(inputField + 'input' + fieldNumber);
|
|
var error = document.getElementById(inputField + fieldNumber + 'Error');
|
|
var success = document.getElementById(inputField + fieldNumber + 'Success');
|
|
var value = field.value.trim();
|
|
|
|
// Validate digits
|
|
|
|
if (value.match(pages)) {
|
|
// Valid
|
|
field.classList.remove('is-invalid');
|
|
field.classList.add('is-valid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'block';
|
|
} else {
|
|
field.classList.remove('is-valid');
|
|
field.classList.add('is-invalid');
|
|
error.style.display = 'block';
|
|
success.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function validatePagesPageAtEnd(inputField, fieldNumber) {
|
|
|
|
const pages = /^[0-9\-\.\s]+(S\.|Seiten)?$/
|
|
|
|
var field = document.getElementById(inputField + 'input' + fieldNumber);
|
|
var error = document.getElementById(inputField + fieldNumber + 'Error');
|
|
var success = document.getElementById(inputField + fieldNumber + 'Success');
|
|
var value = field.value.trim();
|
|
|
|
// Validate digits
|
|
|
|
if (value.match(pages)) {
|
|
// Valid
|
|
field.classList.remove('is-invalid');
|
|
field.classList.add('is-valid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'block';
|
|
} else {
|
|
field.classList.remove('is-valid');
|
|
field.classList.add('is-invalid');
|
|
error.style.display = 'block';
|
|
success.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
|
|
function validateAlphaExtended(inputField, fieldNumber) {
|
|
|
|
const alphanumeric = /^[\p{sc=Latn}\p{Nd}0-9 .,-:\/]*$/u;
|
|
|
|
var field = document.getElementById(inputField + 'input' + fieldNumber);
|
|
var error = document.getElementById(inputField + fieldNumber + 'Error');
|
|
var success = document.getElementById(inputField + fieldNumber + 'Success');
|
|
var value = field.value.trim();
|
|
|
|
// Validate alphanumeric
|
|
|
|
if (value.match(alphanumeric)) {
|
|
// Valid
|
|
field.classList.remove('is-invalid');
|
|
field.classList.add('is-valid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'block';
|
|
} else {
|
|
field.classList.remove('is-valid');
|
|
field.classList.add('is-invalid');
|
|
error.style.display = 'block';
|
|
success.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function validateEmptyEntry(inputField, fieldNumber) {
|
|
|
|
return(validateEmptyTitle(inputField, fieldNumber));
|
|
|
|
}
|
|
|
|
|
|
function validateEmptyTitle(inputField, fieldNumber) {
|
|
|
|
var field = document.getElementById(inputField + 'input' + fieldNumber);
|
|
var error = document.getElementById(inputField + fieldNumber + 'Error');
|
|
var success = document.getElementById(inputField + fieldNumber + 'Success');
|
|
var value = field.value.trim();
|
|
|
|
if (value.length == 0) {
|
|
// Ungültig
|
|
field.classList.remove('is-valid');
|
|
field.classList.add('is-invalid');
|
|
error.style.display = 'block';
|
|
success.style.display = 'none';
|
|
return false
|
|
} else {
|
|
// Gültig
|
|
field.classList.remove('is-invalid');
|
|
field.classList.add('is-valid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'block';
|
|
return true
|
|
}
|
|
}
|
|
|
|
function validateText(inputField, fieldNumber, minLength=4, maxLength=2000) {
|
|
|
|
var field = document.getElementById(inputField + 'input' + fieldNumber);
|
|
var error = document.getElementById(inputField + fieldNumber + 'Error');
|
|
var success = document.getElementById(inputField + fieldNumber + 'Success');
|
|
var value = field.value.trim();
|
|
|
|
if (event.type === 'blur') {
|
|
if (value.length == 0) {
|
|
field.classList.remove('is-valid');
|
|
field.classList.add('is-invalid');
|
|
error.style.display = 'block';
|
|
success.style.display = 'none';
|
|
setTimeout(() => {
|
|
field.focus();
|
|
}, 10);
|
|
return
|
|
}
|
|
}
|
|
|
|
if (value.length <= minLength ) {
|
|
// noch nicht genügend eingetippt - keine Anzeige
|
|
field.classList.remove('is-valid', 'is-invalid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'none';
|
|
} else {
|
|
// Gültig
|
|
field.classList.remove('is-invalid');
|
|
field.classList.add('is-valid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'block';
|
|
}
|
|
}
|
|
|
|
|
|
function validateYear(inputField, fieldNumber) {
|
|
|
|
var yearInput = document.getElementById(inputField + 'input' + fieldNumber);
|
|
var error = document.getElementById(inputField + fieldNumber + 'Error');
|
|
var success = document.getElementById(inputField + fieldNumber + 'Success');
|
|
var value = yearInput.value.trim();
|
|
var result = true;
|
|
|
|
// Leer - keine Anzeige
|
|
yearInput.classList.remove('is-valid', 'is-invalid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'none';
|
|
|
|
yearInput.addEventListener('input', function() {
|
|
const value = this.value;
|
|
|
|
// Erst Regex prüfen
|
|
if (!/^\d{4}$/.test(value)) {
|
|
this.value = value.replace(/\D/g, '').slice(0, 4);
|
|
result = false ;
|
|
}
|
|
|
|
// Wenn 4 Stellen, Jahr validieren
|
|
if (value.length === 4) {
|
|
const year = parseInt(value, 10);
|
|
const currentYear = new Date().getFullYear();
|
|
|
|
if (year > currentYear) {
|
|
result = false;
|
|
} else {
|
|
result = true;
|
|
|
|
}
|
|
}
|
|
if (result === false) {
|
|
yearInput.classList.remove('is-valid');
|
|
yearInput.classList.add('is-invalid');
|
|
error.style.display = 'block';
|
|
success.style.display = 'none';
|
|
setTimeout(() => {
|
|
yearInput.focus();
|
|
}, 10);
|
|
return;
|
|
} else {
|
|
// Gültig
|
|
yearInput.classList.remove('is-invalid');
|
|
yearInput.classList.add('is-valid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'block';
|
|
}
|
|
});
|
|
|
|
yearInput.addEventListener('focusout', function(event) {
|
|
const value = this.value.trim();
|
|
|
|
// Validierung
|
|
if (!isValidYear(value)) {
|
|
event.preventDefault(); // Verhindert das Verlassen des Feldes
|
|
this.focus(); // Focus zurück ins Feld
|
|
yearInput.classList.remove('is-valid');
|
|
yearInput.classList.add('is-invalid');
|
|
error.style.display = 'block';
|
|
success.style.display = 'none';
|
|
setTimeout(() => {
|
|
yearInput.focus();
|
|
}, 10);
|
|
return;
|
|
}
|
|
});
|
|
}
|
|
|
|
function isValidYear(input) {
|
|
|
|
if (!/^\d{4}$/.test(input)) {
|
|
return false;
|
|
}
|
|
const year = parseInt(input, 10);
|
|
const currentYear = new Date().getFullYear();
|
|
return year <= currentYear && year >= 1900; // mit sinnvollem Mindestjahr
|
|
}
|
|
|
|
|
|
|
|
function validateAbstract(inputField, fieldNumber) {
|
|
var field = document.getElementById(inputField + 'input' + fieldNumber);
|
|
var error = document.getElementById(inputField + fieldNumber + 'Error');
|
|
var success = document.getElementById(inputField + fieldNumber + 'Success');
|
|
var value = field.value.trim();
|
|
|
|
if (value.length === 0) {
|
|
// Leer - keine Anzeige
|
|
field.classList.remove('is-valid', 'is-invalid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'none';
|
|
} else if (value.length >= 2800) {
|
|
// Ungültig
|
|
field.classList.remove('is-valid');
|
|
field.classList.add('is-invalid');
|
|
error.style.display = 'block';
|
|
success.style.display = 'none';
|
|
} else {
|
|
// Gültig
|
|
field.classList.remove('is-invalid');
|
|
field.classList.add('is-valid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'block';
|
|
}
|
|
}
|
|
|
|
function validatePID(inputField, fieldNumber) {
|
|
|
|
var selected = document.getElementById(inputField +"_select" +fieldNumber).value;
|
|
var field = document.getElementById(inputField +"Input"+ fieldNumber);
|
|
var error = document.getElementById(inputField + fieldNumber + 'Error');
|
|
var success = document.getElementById(inputField + fieldNumber + 'Success');
|
|
const pid = document.getElementById(inputField +"Input"+ fieldNumber).value;
|
|
|
|
console.log("Selected: " +selected);
|
|
console.log("Value: " +pid);
|
|
result = validateIdentifier(pid, selected);
|
|
|
|
if (result.valid === true) {
|
|
field.classList.remove('is-invalid');
|
|
field.classList.add('is-valid');
|
|
error.style.display = 'none';
|
|
error.innerHTML = '';
|
|
success.style.display = 'block';
|
|
} else {
|
|
field.classList.remove('is-valid');
|
|
field.classList.add('is-invalid');
|
|
error.style.display = 'block';
|
|
error.innerHTML = result.error;
|
|
success.style.display = 'none';
|
|
setTimeout(() => {
|
|
field.focus();
|
|
}, 10);
|
|
return
|
|
}
|
|
|
|
}
|
|
|
|
function deleteErrorMessage(inputField, fieldNumber) {
|
|
|
|
var field = document.getElementById(inputField + 'input' + fieldNumber);
|
|
var error = document.getElementById(inputField + fieldNumber + 'Error');
|
|
|
|
if (error) {
|
|
if(field) {
|
|
field.classList.remove('is-invalid');
|
|
field.classList.add('is-valid');
|
|
field.innerHTML = '';
|
|
}
|
|
error.style.display = 'none';
|
|
error.innerHTML = '';
|
|
}
|
|
}
|
|
|
|
function validateNameFormat(inputField, fieldNumber) {
|
|
|
|
var field = document.getElementById(inputField + 'input' + fieldNumber);
|
|
var error = document.getElementById(inputField + fieldNumber + 'Error');
|
|
var success = document.getElementById(inputField + fieldNumber + 'Success');
|
|
var value = field.value.trim();
|
|
var ret = true
|
|
|
|
// check if input is null or undefined
|
|
|
|
if (!value || typeof value !== 'string') {
|
|
ret = false
|
|
}
|
|
|
|
// Regex to check "name, forename" format. Erlaubt alle UTF-8 Zeichen plus Apostroph und Punkt für Abkürzungen
|
|
const namePattern = /^[\p{L}\s'.-]+,\s*[\p{L}\s'.-]+$/u;
|
|
|
|
if (!namePattern.test(value)) {
|
|
ret = false
|
|
}
|
|
|
|
if (ret === true) {
|
|
field.classList.remove('is-invalid');
|
|
field.classList.add('is-valid');
|
|
error.style.display = 'none';
|
|
success.style.display = 'block';
|
|
} else {
|
|
field.classList.remove('is-valid');
|
|
field.classList.add('is-invalid');
|
|
error.style.display = 'block';
|
|
success.style.display = 'none';
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
|
// Formular zurücksetzen
|
|
function clearForm() {
|
|
const form = document.getElementById('validationForm');
|
|
form.reset();
|
|
form.classList.remove('was-validated');
|
|
|
|
// Custom Field auch zurücksetzen
|
|
const customField = document.getElementById('customField');
|
|
customField.classList.remove('is-valid', 'is-invalid');
|
|
document.getElementById('customError').style.display = 'none';
|
|
document.getElementById('customSuccess').style.display = 'none';
|
|
}
|
|
|
|
|
|
function sendFinalMails(bibliographicArray, identificatorArray, typeArray, subjectArray, contractArray) {
|
|
const relevantDivs = ["BibliographicData", "IdentificatorData", "TypeData", "SubjectData", "contractData", "uploadData"];
|
|
|
|
// Globale Arrays für die Daten
|
|
let bibliographicDataArray = [];
|
|
let identificatorDataArray = [];
|
|
let typeDataArray = [];
|
|
let subjectDataArray = [];
|
|
let contractDataArray = [];
|
|
let uploadDataArray = [];
|
|
|
|
bibliographicDataArray = readDataFromDiv('BibliographicData');
|
|
identificatorDataArray = readDataFromDiv('IdentificatorData');
|
|
typeDataArray = readDataFromDiv('TypeData');
|
|
subjectDataArray = readDataFromDiv('SubjectData');
|
|
contractDataArray = readDataFromDiv('contractData');
|
|
uploadDataArray = readDataFromUploadDiv('fileList');
|
|
|
|
// Console ausgeben
|
|
console.log('BibliographicData Array:', bibliographicDataArray);
|
|
console.log('IdentificatorData Array:', identificatorDataArray);
|
|
console.log('TypeData Array:', typeDataArray);
|
|
console.log('SubjectData Array:', subjectDataArray);
|
|
console.log('ContractData Array:', contractDataArray);
|
|
console.log('UploadData Array:', uploadDataArray);
|
|
|
|
// Einfaches JavaScript-Objekt für jQuery $.post()
|
|
var postData = {
|
|
bibliographicArray: JSON.stringify(bibliographicDataArray),
|
|
identificatorArray: JSON.stringify(identificatorDataArray),
|
|
typeArray: JSON.stringify(typeDataArray),
|
|
subjectArray: JSON.stringify(subjectDataArray),
|
|
contractArray: JSON.stringify(contractDataArray),
|
|
uploadArray: JSON.stringify(uploadDataArray)
|
|
};
|
|
|
|
// AJAX-Aufruf
|
|
$.post('sendFinalMails.php', postData, function(data, status) {
|
|
if (status == "success") {
|
|
hideElement("BibliographicData");
|
|
hideElement("IdentificatorData");
|
|
hideElement("TypeData");
|
|
hideElement("SubjectData");
|
|
hideElement("contractData");
|
|
hideElement("uploadData");
|
|
hideElement("divSummaryButton");
|
|
hideElement("summaryButton");
|
|
|
|
const VERODataDiv = document.getElementById("VEROData");
|
|
//if (VERODataDiv && VERODataDiv.style.display !== 'none') {
|
|
// VERODataDiv.style.display = 'none';
|
|
//}
|
|
|
|
//alert(data);
|
|
const MailDataDiv = document.getElementById("finalMailContent");
|
|
MailDataDiv.innerHTML = data;
|
|
|
|
const MailDiv = document.getElementById("MAILData");
|
|
if (MailDiv && MailDiv.style.display !== 'block') {
|
|
// alert("MAILdata auf block gestellt");
|
|
MailDiv.style.display = 'block';
|
|
}
|
|
console.log(MailDiv);
|
|
} else {
|
|
alert("Mail konnte nicht verschickt werden: " + data);
|
|
}
|
|
}).fail(function(xhr, status, error) {
|
|
alert("AJAX-Fehler: " + error);
|
|
});
|
|
}
|
|
|
|
|
|
// Accordion Validierung - verhindert das Schließen bei fehlenden required Feldern
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Event Listener für alle Accordion Buttons
|
|
const accordionButtons = document.querySelectorAll('[data-bs-toggle="collapse"]');
|
|
|
|
accordionButtons.forEach(button => {
|
|
button.addEventListener('click', function(e) {
|
|
const targetId = this.getAttribute('data-bs-target');
|
|
const targetAccordion = document.querySelector(targetId);
|
|
|
|
// Prüfen ob das Accordion aktuell geöffnet ist und geschlossen werden soll
|
|
if (targetAccordion && targetAccordion.classList.contains('show')) {
|
|
// Validierung durchführen
|
|
if (!validateAccordionContent(targetAccordion)) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
// Bootstrap Accordion Event abfangen (zusätzliche Sicherheit)
|
|
const accordionElement = document.getElementById('TypeData');
|
|
if (accordionElement) {
|
|
accordionElement.addEventListener('hide.bs.collapse', function(e) {
|
|
if (!validateAccordionContent(e.target)) {
|
|
e.preventDefault();
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
function validateAccordionContent(accordionContent) {
|
|
// Prüfen ob wir im Dokumenttyp-Auswahl-Modus sind
|
|
const checkBoxTypeDiv = document.getElementById("checkBoxType");
|
|
if (checkBoxTypeDiv && checkBoxTypeDiv.style.display !== 'none') {
|
|
// Im Auswahl-Modus - nur prüfen ob ein Dokumenttyp gewählt wurde
|
|
const selectedType = document.querySelector('input[name="checkType"]:checked');
|
|
if (!selectedType) {
|
|
showValidationError('Bitte wählen Sie einen Dokumenttyp aus.');
|
|
return false;
|
|
}
|
|
// Dokumenttyp gewählt - Validierung bestanden
|
|
return true;
|
|
}
|
|
|
|
// Im Detail-Modus - normale Feldvalidierung
|
|
const selectedType = document.querySelector('input[name="checkType"]:checked');
|
|
if (!selectedType) {
|
|
// Das sollte nicht passieren, aber sicherheitshalber
|
|
backToDocumentTypeSelection();
|
|
return false;
|
|
}
|
|
|
|
// Nur die Felder des gewählten Dokumenttyps validieren
|
|
const activeDiv = getActiveDivForDocumentType(selectedType.value);
|
|
if (!activeDiv) {
|
|
return true; // Kein spezifischer Div gefunden, Validierung übersprungen
|
|
}
|
|
|
|
// Required Felder nur im aktiven Div suchen
|
|
const requiredFields = activeDiv.querySelectorAll('input[required], textarea[required], select[required]');
|
|
let allValid = true;
|
|
let firstInvalidField = null;
|
|
|
|
requiredFields.forEach(field => {
|
|
// Zusätzliche Sichtbarkeits-Prüfung für nested Elemente
|
|
if (isFieldInActiveArea(field, activeDiv)) {
|
|
if (!field.value.trim()) {
|
|
allValid = false;
|
|
if (!firstInvalidField) {
|
|
firstInvalidField = field;
|
|
}
|
|
|
|
// Feld als ungültig markieren
|
|
markFieldAsInvalid(field);
|
|
}
|
|
}
|
|
});
|
|
|
|
if (!allValid) {
|
|
// Fehlermeldung anzeigen
|
|
showValidationError('Bitte füllen Sie alle Pflichtfelder für den gewählten Dokumenttyp aus.');
|
|
|
|
// Zum ersten ungültigen Feld scrollen
|
|
if (firstInvalidField) {
|
|
firstInvalidField.focus();
|
|
firstInvalidField.scrollIntoView({
|
|
behavior: 'smooth',
|
|
block: 'center'
|
|
});
|
|
}
|
|
}
|
|
|
|
return allValid;
|
|
}
|
|
|
|
// Hilfsfunktion: Aktiven Div für gewählten Dokumenttyp ermitteln
|
|
function getActiveDivForDocumentType(documentType) {
|
|
switch(documentType) {
|
|
case 'Zeitschriftenartikel':
|
|
return document.getElementById('divZeitschriftenartikel');
|
|
case 'Sammelbandbeitrag':
|
|
return document.getElementById('divSammelbandbeitrag');
|
|
case 'Monografie':
|
|
return document.getElementById('divMonografie');
|
|
case 'Qualifikationsarbeit':
|
|
return document.getElementById('divQualifikationsarbeit');
|
|
case 'Konferenzbeitrag': // Falls Sie diesen auch haben
|
|
return document.getElementById('divKonferenzbeitrag');
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Hilfsfunktion: Prüfen ob Feld im aktiven Bereich ist
|
|
function isFieldInActiveArea(field, activeDiv) {
|
|
// Prüfen ob das Feld ein Nachfahre des aktiven Divs ist
|
|
return activeDiv.contains(field) && isFieldActuallyVisible(field);
|
|
}
|
|
|
|
function isFieldActuallyVisible(field) {
|
|
// Prüfen ob das Feld und seine direkten Container sichtbar sind
|
|
let element = field;
|
|
while (element && element !== document.body) {
|
|
const style = window.getComputedStyle(element);
|
|
if (style.display === 'none' || style.visibility === 'hidden') {
|
|
return false;
|
|
}
|
|
element = element.parentElement;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function markFieldAsInvalid(field) {
|
|
// Bootstrap Validation Klassen hinzufügen
|
|
field.classList.add('is-invalid');
|
|
|
|
// Bestehende Error-Divs anzeigen (falls vorhanden)
|
|
const fieldId = field.id;
|
|
if (fieldId) {
|
|
const errorDiv = document.getElementById(fieldId.replace('input', '') + 'Error');
|
|
if (errorDiv) {
|
|
errorDiv.style.display = 'block';
|
|
}
|
|
}
|
|
|
|
// Event Listener für Änderungen am Feld
|
|
field.addEventListener('input', function() {
|
|
if (this.value.trim()) {
|
|
this.classList.remove('is-invalid');
|
|
this.classList.add('is-valid');
|
|
|
|
// Error div ausblenden
|
|
const fieldId = this.id;
|
|
if (fieldId) {
|
|
const errorDiv = document.getElementById(fieldId.replace('input', '') + 'Error');
|
|
if (errorDiv) {
|
|
errorDiv.style.display = 'none';
|
|
}
|
|
}
|
|
}
|
|
}, { once: true });
|
|
}
|
|
|
|
function showValidationError(message = 'Bitte füllen Sie alle Pflichtfelder aus, bevor Sie fortfahren.') {
|
|
// Toast oder Alert für Fehlermeldung
|
|
if (typeof bootstrap !== 'undefined' && bootstrap.Toast) {
|
|
// Bootstrap Toast verwenden
|
|
const toastHtml = `
|
|
<div class="toast align-items-center text-white bg-danger border-0" role="alert" aria-live="assertive" aria-atomic="true">
|
|
<div class="d-flex">
|
|
<div class="toast-body">
|
|
<strong>Fehler:</strong> ${message}
|
|
</div>
|
|
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
// Toast Container erstellen falls nicht vorhanden
|
|
let toastContainer = document.getElementById('toast-container');
|
|
if (!toastContainer) {
|
|
toastContainer = document.createElement('div');
|
|
toastContainer.id = 'toast-container';
|
|
toastContainer.className = 'toast-container position-fixed top-0 end-0 p-3';
|
|
toastContainer.style.zIndex = '1055';
|
|
document.body.appendChild(toastContainer);
|
|
}
|
|
|
|
// Toast hinzufügen und anzeigen
|
|
toastContainer.innerHTML = toastHtml;
|
|
const toastElement = toastContainer.querySelector('.toast');
|
|
const toast = new bootstrap.Toast(toastElement);
|
|
toast.show();
|
|
|
|
} else {
|
|
// Fallback: einfaches Alert
|
|
alert(message);
|
|
}
|
|
}
|
|
|
|
// Hilfsfunktion: Alle Felder in einem Accordion validieren
|
|
function validateAllFieldsInAccordion(accordionId) {
|
|
const accordion = document.getElementById(accordionId);
|
|
if (accordion) {
|
|
const collapseElement = accordion.querySelector('.accordion-collapse');
|
|
return validateAccordionContent(collapseElement);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Hilfsfunktion: Validierung für spezifische Dokumenttypen
|
|
function validateDocumentTypeFields() {
|
|
const selectedType = document.querySelector('input[name="checkType"]:checked');
|
|
if (!selectedType) {
|
|
return false;
|
|
}
|
|
|
|
const typeValue = selectedType.value;
|
|
let targetDiv = null;
|
|
|
|
switch(typeValue) {
|
|
case 'Zeitschriftenartikel':
|
|
targetDiv = document.getElementById('divZeitschriftenartikel');
|
|
break;
|
|
case 'Sammelbandbeitrag':
|
|
targetDiv = document.getElementById('divSammelbandbeitrag');
|
|
break;
|
|
case 'Monografie':
|
|
targetDiv = document.getElementById('divMonografie');
|
|
break;
|
|
case 'Qualifikationsarbeit':
|
|
targetDiv = document.getElementById('divQualifikationsarbeit');
|
|
break;
|
|
}
|
|
|
|
if (targetDiv) {
|
|
return validateAccordionContent(targetDiv);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Angepasste checkBoxType Funktion
|
|
function checkBoxType(selectedType) {
|
|
// Alle Dokumenttyp-Divs ausblenden
|
|
const allTypeDivs = [
|
|
'divMonografie',
|
|
'divSammelbandbeitrag',
|
|
'divZeitschriftenartikel',
|
|
'divKonferenzbeitrag',
|
|
'divQualifikationsarbeit'
|
|
];
|
|
|
|
allTypeDivs.forEach(divId => {
|
|
const div = document.getElementById(divId);
|
|
if (div) {
|
|
div.style.display = 'none';
|
|
}
|
|
});
|
|
|
|
// Validierungsklassen von allen Feldern entfernen
|
|
allTypeDivs.forEach(divId => {
|
|
const div = document.getElementById(divId);
|
|
if (div) {
|
|
const fields = div.querySelectorAll('.is-invalid, .is-valid');
|
|
fields.forEach(field => {
|
|
field.classList.remove('is-invalid', 'is-valid');
|
|
});
|
|
|
|
// Error Divs ausblenden
|
|
const errorDivs = div.querySelectorAll('[id$="Error"]');
|
|
errorDivs.forEach(errorDiv => {
|
|
errorDiv.style.display = 'none';
|
|
});
|
|
}
|
|
});
|
|
|
|
// Entsprechenden Div für gewählten Typ einblenden
|
|
let targetDivId = null;
|
|
switch(selectedType) {
|
|
case 'Zeitschriftenartikel':
|
|
targetDivId = 'divZeitschriftenartikel';
|
|
break;
|
|
case 'Sammelbandbeitrag':
|
|
targetDivId = 'divSammelbandbeitrag';
|
|
break;
|
|
case 'Monografie':
|
|
targetDivId = 'divMonografie';
|
|
break;
|
|
case 'Qualifikationsarbeit':
|
|
targetDivId = 'divQualifikationsarbeit';
|
|
break;
|
|
case 'Konferenzbeitrag':
|
|
targetDivId = 'divKonferenzbeitrag';
|
|
break;
|
|
}
|
|
|
|
if (targetDivId) {
|
|
const targetDiv = document.getElementById(targetDivId);
|
|
if (targetDiv) {
|
|
targetDiv.style.display = 'block';
|
|
}
|
|
}
|
|
|
|
// Dokumenttyp-Auswahl ausblenden
|
|
const checkBoxTypeDiv = document.getElementById("checkBoxType");
|
|
if (checkBoxTypeDiv) {
|
|
checkBoxTypeDiv.style.display = 'none';
|
|
}
|
|
|
|
// Zurück-Button hinzufügen/anzeigen
|
|
showBackToSelectionButton();
|
|
}
|
|
|
|
// Funktion für Zurück-Button
|
|
function showBackToSelectionButton() {
|
|
// Prüfen ob Button bereits existiert
|
|
let backButton = document.getElementById('backToDocumentTypeSelection');
|
|
|
|
if (!backButton) {
|
|
// Button erstellen
|
|
backButton = document.createElement('div');
|
|
backButton.id = 'backToDocumentTypeSelection';
|
|
backButton.className = 'mb-3';
|
|
backButton.innerHTML = `
|
|
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="backToDocumentTypeSelection()">
|
|
<i class="bi bi-arrow-left"></i> Zurück zur Dokumenttyp-Auswahl
|
|
</button>
|
|
`;
|
|
|
|
// Button nach dem typeBox einfügen
|
|
const typeBox = document.getElementById('typeBox');
|
|
if (typeBox && typeBox.parentNode) {
|
|
typeBox.parentNode.insertBefore(backButton, typeBox.nextSibling);
|
|
}
|
|
}
|
|
|
|
// Button anzeigen
|
|
backButton.style.display = 'block';
|
|
}
|
|
|
|
// Zurück zur Dokumenttyp-Auswahl
|
|
function backToDocumentTypeSelection() {
|
|
// Alle Dokumenttyp-Divs ausblenden
|
|
const allTypeDivs = [
|
|
'divMonografie',
|
|
'divSammelbandbeitrag',
|
|
'divZeitschriftenartikel',
|
|
'divKonferenzbeitrag',
|
|
'divQualifikationsarbeit'
|
|
];
|
|
|
|
allTypeDivs.forEach(divId => {
|
|
const div = document.getElementById(divId);
|
|
if (div) {
|
|
div.style.display = 'none';
|
|
}
|
|
});
|
|
|
|
// Dokumenttyp-Auswahl wieder einblenden
|
|
const checkBoxTypeDiv = document.getElementById("checkBoxType");
|
|
if (checkBoxTypeDiv) {
|
|
checkBoxTypeDiv.style.display = 'block';
|
|
}
|
|
|
|
// Zurück-Button ausblenden
|
|
const backButton = document.getElementById('backToDocumentTypeSelection');
|
|
if (backButton) {
|
|
backButton.style.display = 'none';
|
|
}
|
|
|
|
// Radio-Button Auswahl zurücksetzen (optional)
|
|
const radioButtons = document.querySelectorAll('input[name="checkType"]');
|
|
radioButtons.forEach(radio => {
|
|
radio.checked = false;
|
|
});
|
|
|
|
// Alle Validierungsklassen entfernen
|
|
allTypeDivs.forEach(divId => {
|
|
const div = document.getElementById(divId);
|
|
if (div) {
|
|
const fields = div.querySelectorAll('.is-invalid, .is-valid');
|
|
fields.forEach(field => {
|
|
field.classList.remove('is-invalid', 'is-valid');
|
|
field.value = ''; // Felder leeren (optional)
|
|
});
|
|
|
|
// Error Divs ausblenden
|
|
const errorDivs = div.querySelectorAll('[id$="Error"]');
|
|
errorDivs.forEach(errorDiv => {
|
|
errorDiv.style.display = 'none';
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// Initialisierung beim Laden der Seite
|
|
function initializeDocumentTypeSelection() {
|
|
// Sicherstellen, dass alle Detail-Divs ausgeblendet sind
|
|
const allTypeDivs = [
|
|
'divMonografie',
|
|
'divSammelbandbeitrag',
|
|
'divZeitschriftenartikel',
|
|
'divKonferenzbeitrag',
|
|
'divQualifikationsarbeit'
|
|
];
|
|
|
|
allTypeDivs.forEach(divId => {
|
|
const div = document.getElementById(divId);
|
|
if (div) {
|
|
div.style.display = 'none';
|
|
}
|
|
});
|
|
|
|
// Sicherstellen, dass checkBoxType sichtbar ist
|
|
const checkBoxTypeDiv = document.getElementById("checkBoxType");
|
|
if (checkBoxTypeDiv) {
|
|
checkBoxTypeDiv.style.display = 'block';
|
|
}
|
|
|
|
// Zurück-Button ausblenden
|
|
const backButton = document.getElementById('backToDocumentTypeSelection');
|
|
if (backButton) {
|
|
backButton.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
// Beim Laden der Seite initialisieren
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
initializeDocumentTypeSelection();
|
|
});
|
|
|
|
|
|
// Sanitize Funktionen
|
|
|
|
/**
|
|
* JavaScript Input Sanitization Functions (Prozedural)
|
|
* Verschiedene Funktionen zum Bereinigen von User-Inputs
|
|
*/
|
|
|
|
/**
|
|
* HTML-Tags und gefährliche Zeichen entfernen/escapen
|
|
* @param {string} input
|
|
* @returns {string}
|
|
*/
|
|
function sanitizeHTML(input) {
|
|
if (typeof input !== 'string') return '';
|
|
|
|
return input
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
.replace(/'/g, ''')
|
|
.replace(/\//g, '/');
|
|
}
|
|
|
|
/**
|
|
* SQL Injection Zeichen escapen (für dynamische Queries)
|
|
* @param {string} input
|
|
* @returns {string}
|
|
*/
|
|
function sanitizeSQL(input) {
|
|
if (typeof input !== 'string') return '';
|
|
|
|
return input
|
|
.replace(/'/g, "''") // Single quotes escapen
|
|
.replace(/"/g, '""') // Double quotes escapen
|
|
.replace(/\\/g, '\\\\') // Backslashes escapen
|
|
.replace(/\0/g, '\\0') // Null bytes
|
|
.replace(/\n/g, '\\n') // Newlines
|
|
.replace(/\r/g, '\\r') // Carriage returns
|
|
.replace(/\x1a/g, '\\Z'); // Ctrl+Z
|
|
}
|
|
|
|
/**
|
|
* Email-Adresse validieren und bereinigen
|
|
* @param {string} email
|
|
* @returns {string|null}
|
|
*/
|
|
function sanitizeEmail(email) {
|
|
if (typeof email !== 'string') return null;
|
|
|
|
// Whitespace entfernen und lowercase
|
|
email = email.trim().toLowerCase();
|
|
|
|
// Basis Email Regex
|
|
const emailRegex = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/;
|
|
|
|
return emailRegex.test(email) ? email : null;
|
|
}
|
|
|
|
/**
|
|
* Telefonnummer bereinigen (nur Zahlen, +, -, (, ), Leerzeichen)
|
|
* @param {string} phone
|
|
* @returns {string}
|
|
*/
|
|
function sanitizePhone(phone) {
|
|
if (typeof phone !== 'string') return '';
|
|
|
|
// Nur erlaubte Zeichen behalten
|
|
return phone.replace(/[^0-9+\-\(\)\s]/g, '').trim();
|
|
}
|
|
|
|
/**
|
|
* URL validieren und bereinigen
|
|
* @param {string} url
|
|
* @returns {string|null}
|
|
*/
|
|
function sanitizeURL(url) {
|
|
if (typeof url !== 'string') return null;
|
|
|
|
url = url.trim();
|
|
|
|
try {
|
|
const urlObj = new URL(url);
|
|
// Nur HTTP/HTTPS erlauben
|
|
if (urlObj.protocol === 'http:' || urlObj.protocol === 'https:') {
|
|
return urlObj.href;
|
|
}
|
|
} catch (e) {
|
|
// Falls URL ungültig ist
|
|
return null;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Numerische Inputs bereinigen
|
|
* @param {string|number} input
|
|
* @param {number|null} min - Minimum Wert
|
|
* @param {number|null} max - Maximum Wert
|
|
* @param {number|null} decimals - Anzahl Dezimalstellen
|
|
* @returns {number|null}
|
|
*/
|
|
function sanitizeNumber(input, min = null, max = null, decimals = null) {
|
|
// Zu Number konvertieren
|
|
let num = parseFloat(input);
|
|
|
|
if (isNaN(num)) return null;
|
|
|
|
// Dezimalstellen begrenzen
|
|
if (decimals !== null) {
|
|
num = parseFloat(num.toFixed(decimals));
|
|
}
|
|
|
|
// Min/Max Grenzen prüfen
|
|
if (min !== null && num < min) return null;
|
|
if (max !== null && num > max) return null;
|
|
|
|
return num;
|
|
}
|
|
|
|
/**
|
|
* Integer bereinigen
|
|
* @param {string|number} input
|
|
* @param {number|null} min
|
|
* @param {number|null} max
|
|
* @returns {number|null}
|
|
*/
|
|
function sanitizeInteger(input, min = null, max = null) {
|
|
const num = parseInt(input);
|
|
|
|
if (isNaN(num)) return null;
|
|
|
|
if (min !== null && num < min) return null;
|
|
if (max !== null && num > max) return null;
|
|
|
|
return num;
|
|
}
|
|
|
|
/**
|
|
* Allgemeine Textbereinigung
|
|
* @param {string} input
|
|
* @param {number|null} maxLength
|
|
* @param {string|null} allowedCharsRegex - Regex Pattern für erlaubte Zeichen
|
|
* @param {boolean} trim
|
|
* @param {boolean} removeMultipleSpaces
|
|
* @returns {string}
|
|
*/
|
|
function sanitizeText(input, maxLength = null, allowedCharsRegex = null, trim = true, removeMultipleSpaces = true) {
|
|
if (typeof input !== 'string') return '';
|
|
|
|
let sanitized = input;
|
|
|
|
// Trimmen
|
|
if (trim) {
|
|
sanitized = sanitized.trim();
|
|
}
|
|
|
|
// Mehrfache Leerzeichen entfernen
|
|
if (removeMultipleSpaces) {
|
|
sanitized = sanitized.replace(/\s+/g, ' ');
|
|
}
|
|
|
|
// Nur erlaubte Zeichen behalten
|
|
if (allowedCharsRegex) {
|
|
const regex = new RegExp(allowedCharsRegex, 'g');
|
|
const matches = sanitized.match(regex);
|
|
sanitized = matches ? matches.join('') : '';
|
|
}
|
|
|
|
// Länge begrenzen
|
|
if (maxLength && sanitized.length > maxLength) {
|
|
sanitized = sanitized.substring(0, maxLength);
|
|
}
|
|
|
|
return sanitized;
|
|
}
|
|
|
|
/**
|
|
* Username bereinigen (nur Buchstaben, Zahlen, Underscore)
|
|
* @param {string} username
|
|
* @param {number} minLength
|
|
* @param {number} maxLength
|
|
* @returns {string|null}
|
|
*/
|
|
function sanitizeUsername(username, minLength = 3, maxLength = 20) {
|
|
if (typeof username !== 'string') return null;
|
|
|
|
// Nur erlaubte Zeichen, trim, lowercase
|
|
const sanitized = username
|
|
.trim()
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9_]/g, '');
|
|
|
|
// Länge prüfen
|
|
if (sanitized.length < minLength || sanitized.length > maxLength) {
|
|
return null;
|
|
}
|
|
|
|
// Nicht mit Zahl oder Underscore beginnen
|
|
if (/^[0-9_]/.test(sanitized)) {
|
|
return null;
|
|
}
|
|
|
|
return sanitized;
|
|
}
|
|
|
|
/**
|
|
* Dateinamen bereinigen
|
|
* @param {string} filename
|
|
* @returns {string}
|
|
*/
|
|
function sanitizeFilename(filename) {
|
|
if (typeof filename !== 'string') return '';
|
|
|
|
return filename
|
|
.replace(/[<>:"/\\|?*\x00-\x1f]/g, '') // Ungültige Zeichen entfernen
|
|
.replace(/^\.+/, '') // Führende Punkte entfernen
|
|
.replace(/\.+$/, '') // Trailing Punkte entfernen
|
|
.replace(/\s+/g, '_') // Leerzeichen durch Unterstriche
|
|
.substring(0, 255); // Max Länge
|
|
}
|
|
|
|
/**
|
|
* XSS-sichere Ausgabe für HTML-Attribute
|
|
* @param {string} input
|
|
* @returns {string}
|
|
*/
|
|
function sanitizeAttribute(input) {
|
|
if (typeof input !== 'string') return '';
|
|
|
|
return input
|
|
.replace(/&/g, '&')
|
|
.replace(/"/g, '"')
|
|
.replace(/'/g, ''')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>');
|
|
}
|
|
|
|
/**
|
|
* Boolean Wert aus String extrahieren
|
|
* @param {string|boolean} input
|
|
* @returns {boolean|null}
|
|
*/
|
|
function sanitizeBoolean(input) {
|
|
if (typeof input === 'boolean') return input;
|
|
if (typeof input !== 'string') return null;
|
|
|
|
const lower = input.toLowerCase().trim();
|
|
|
|
if (['true', '1', 'yes', 'on', 'enabled'].includes(lower)) {
|
|
return true;
|
|
}
|
|
|
|
if (['false', '0', 'no', 'off', 'disabled'].includes(lower)) {
|
|
return false;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Passwort validieren (keine Bereinigung, nur Validation)
|
|
* @param {string} password
|
|
* @returns {object}
|
|
*/
|
|
function validatePassword(password) {
|
|
if (typeof password !== 'string') {
|
|
return { valid: false, errors: ['Password must be a string'], strength: 'invalid' };
|
|
}
|
|
|
|
const errors = [];
|
|
|
|
if (password.length < 8) errors.push('Minimum 8 characters required');
|
|
if (!/[a-z]/.test(password)) errors.push('Lowercase letter required');
|
|
if (!/[A-Z]/.test(password)) errors.push('Uppercase letter required');
|
|
if (!/[0-9]/.test(password)) errors.push('Number required');
|
|
if (!/[^a-zA-Z0-9]/.test(password)) errors.push('Special character required');
|
|
|
|
return {
|
|
valid: errors.length === 0,
|
|
errors: errors,
|
|
strength: getPasswordStrength(password)
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Passwort Stärke berechnen
|
|
* @param {string} password
|
|
* @returns {string}
|
|
*/
|
|
function getPasswordStrength(password) {
|
|
if (typeof password !== 'string') return 'invalid';
|
|
|
|
let score = 0;
|
|
|
|
if (password.length >= 8) score++;
|
|
if (password.length >= 12) score++;
|
|
if (/[a-z]/.test(password)) score++;
|
|
if (/[A-Z]/.test(password)) score++;
|
|
if (/[0-9]/.test(password)) score++;
|
|
if (/[^a-zA-Z0-9]/.test(password)) score++;
|
|
if (password.length >= 16) score++;
|
|
|
|
if (score <= 2) return 'weak';
|
|
if (score <= 4) return 'medium';
|
|
if (score <= 6) return 'strong';
|
|
return 'very-strong';
|
|
}
|
|
|
|
/**
|
|
* Hex Color Code validieren
|
|
* @param {string} color
|
|
* @returns {string|null}
|
|
*/
|
|
function sanitizeHexColor(color) {
|
|
if (typeof color !== 'string') return null;
|
|
|
|
// # entfernen falls vorhanden
|
|
color = color.replace('#', '');
|
|
|
|
// Nur 3 oder 6 Zeichen erlaubt
|
|
if (!/^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{6}$/.test(color)) {
|
|
return null;
|
|
}
|
|
|
|
return '#' + color.toLowerCase();
|
|
}
|
|
|
|
/**
|
|
* Array von Strings bereinigen
|
|
* @param {Array} arr
|
|
* @param {Function} sanitizeFunc - Sanitization Funktion für jeden String
|
|
* @returns {Array}
|
|
*/
|
|
function sanitizeStringArray(arr, sanitizeFunc = sanitizeText) {
|
|
if (!Array.isArray(arr)) return [];
|
|
|
|
return arr
|
|
.filter(item => typeof item === 'string')
|
|
.map(item => sanitizeFunc(item))
|
|
.filter(item => item !== null && item !== '');
|
|
}
|
|
|
|
|
|
// Funktion zum Zurücksetzen aller Radio-Buttons
|
|
function resetAllRadios() {
|
|
// Alle Radio-Buttons in den relevanten Formularen finden und zurücksetzen
|
|
const radioGroups = [
|
|
'publishType',
|
|
'licenseType',
|
|
'zweitveroeffentlichungSelect',
|
|
'OAlicenseType'
|
|
];
|
|
|
|
radioGroups.forEach(groupName => {
|
|
const radios = document.querySelectorAll(`input[name="${groupName}"]`);
|
|
radios.forEach(radio => {
|
|
radio.checked = false;
|
|
});
|
|
});
|
|
|
|
// Alle Checkboxen zurücksetzen
|
|
const checkboxes = document.querySelectorAll('.validation-checkbox');
|
|
checkboxes.forEach(checkbox => {
|
|
checkbox.checked = false;
|
|
});
|
|
|
|
// Verstecke alle spezifischen Sektionen
|
|
hideAllSections();
|
|
|
|
// Validierungsstatus zurücksetzen
|
|
updateValidationStatus();
|
|
}
|
|
|
|
// Funktion zum Verstecken aller Sektionen
|
|
function hideAllSections() {
|
|
const sectionsToHide = [
|
|
'divErstveroeffentlichungOpenAccess',
|
|
'divErstUrh',
|
|
'divZweitveroeffentlichungOpenAccess',
|
|
'divZweitUrh4A',
|
|
'divZweitUrh4B',
|
|
'divCommon',
|
|
'Select4A4B',
|
|
'erstVeroeffentlichtSection',
|
|
'mitteilungSection'
|
|
];
|
|
|
|
sectionsToHide.forEach(sectionId => {
|
|
const section = document.getElementById(sectionId);
|
|
if (section) {
|
|
section.style.display = 'none';
|
|
}
|
|
});
|
|
}
|
|
|
|
// Event Listener für publishType Radio-Buttons
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Warte einen Moment, um sicherzustellen, dass alle Elemente geladen sind
|
|
setTimeout(() => {
|
|
console.log('DOM Content Loaded - Initialisiere Event Listener');
|
|
|
|
// Debug: Prüfe verfügbare Elemente
|
|
debugElements();
|
|
|
|
const publishTypeRadios = document.querySelectorAll('input[name="publishType"]');
|
|
const licenseTypeRadios = document.querySelectorAll('input[name="licenseType"]');
|
|
|
|
console.log('publishType Radios gefunden:', publishTypeRadios.length);
|
|
console.log('licenseType Radios gefunden:', licenseTypeRadios.length);
|
|
|
|
// Event Listener für publishType
|
|
publishTypeRadios.forEach(radio => {
|
|
radio.addEventListener('change', function() {
|
|
console.log('publishType geändert zu:', this.value);
|
|
// Nur andere Radio-Gruppen zurücksetzen, nicht die eigene
|
|
resetSpecificRadioGroups(['licenseType', 'zweitveroeffentlichungSelect', 'OAlicenseType']);
|
|
resetAllCheckboxes();
|
|
hideAllSections();
|
|
|
|
// Nach dem Zurücksetzen prüfen ob eine neue Auswahl getroffen werden kann
|
|
setTimeout(() => {
|
|
checkMultiPublish();
|
|
}, 10);
|
|
});
|
|
});
|
|
|
|
// Event Listener für licenseType
|
|
licenseTypeRadios.forEach(radio => {
|
|
radio.addEventListener('change', function() {
|
|
console.log('licenseType geändert zu:', this.value);
|
|
// Nur abhängige Radio-Gruppen zurücksetzen
|
|
resetSpecificRadioGroups(['zweitveroeffentlichungSelect', 'OAlicenseType']);
|
|
resetAllCheckboxes();
|
|
|
|
// Nicht alle Sektionen verstecken, sondern direkt checkMultiPublish aufrufen
|
|
checkMultiPublish();
|
|
});
|
|
});
|
|
|
|
// Event Listener für zweitveroeffentlichungSelect
|
|
/* const zweitveroeffentlichungRadios = document.querySelectorAll('input[name="zweitveroeffentlichungSelect"]');
|
|
zweitveroeffentlichungRadios.forEach(radio => {
|
|
radio.addEventListener('change', function() {
|
|
console.log('zweitveroeffentlichungSelect geändert zu:', this.value);
|
|
showNextStep(this.value);
|
|
});
|
|
});
|
|
*/
|
|
// Event Listener für OAlicenseType
|
|
const oaLicenseRadios = document.querySelectorAll('input[name="OAlicenseType"]');
|
|
oaLicenseRadios.forEach(radio => {
|
|
radio.addEventListener('change', function() {
|
|
console.log('OAlicenseType geändert zu:', this.value);
|
|
updateValidationStatus();
|
|
});
|
|
});
|
|
|
|
// Event Listener für Checkboxen, um Status zu aktualisieren
|
|
const checkboxes = document.querySelectorAll('.validation-checkbox');
|
|
checkboxes.forEach(checkbox => {
|
|
checkbox.addEventListener('change', function() {
|
|
console.log('Checkbox geändert:', this.id, this.checked);
|
|
updateValidationStatus();
|
|
});
|
|
});
|
|
|
|
// Initial status update
|
|
updateValidationStatus();
|
|
}, 100);
|
|
});
|
|
|
|
// Hilfsfunktion zum Zurücksetzen spezifischer Radio-Gruppen
|
|
function resetSpecificRadioGroups(groupNames) {
|
|
groupNames.forEach(groupName => {
|
|
const radios = document.querySelectorAll(`input[name="${groupName}"]`);
|
|
radios.forEach(radio => {
|
|
radio.checked = false;
|
|
});
|
|
});
|
|
}
|
|
|
|
// Hilfsfunktion zum Zurücksetzen aller Checkboxen
|
|
function resetAllCheckboxes() {
|
|
const checkboxes = document.querySelectorAll('.validation-checkbox');
|
|
checkboxes.forEach(checkbox => {
|
|
checkbox.checked = false;
|
|
});
|
|
}
|
|
|
|
// Erweiterte checkMultiPublish Funktion
|
|
function checkMultiPublish() {
|
|
const publishType = document.querySelector('input[name="publishType"]:checked');
|
|
const licenseType = document.querySelector('input[name="licenseType"]:checked');
|
|
|
|
console.log('checkMultiPublish aufgerufen:', {
|
|
publishType: publishType ? publishType.value : 'none',
|
|
licenseType: licenseType ? licenseType.value : 'none'
|
|
});
|
|
|
|
// Alle Sektionen zunächst verstecken
|
|
hideAllSections();
|
|
|
|
if (publishType && licenseType) {
|
|
const publishTypeSelection = publishType;
|
|
const licenseTypeSelection = licenseType;
|
|
|
|
console.log('Zeige Sektionen für:', publishTypeSelection.value, '+', licenseTypeSelection.value);
|
|
|
|
// Logik für die Anzeige der entsprechenden Sektionen
|
|
|
|
if (publishTypeSelection.value == 'Erstveröffentlichung' && licenseTypeSelection.value == 'CC-Lizenz') {
|
|
showElement("divErstveroeffentlichungOpenAccess");
|
|
showElement("divCommon");
|
|
showElement("mitteilungSection");
|
|
}
|
|
|
|
if (publishTypeSelection.value == 'Erstveröffentlichung' && licenseTypeSelection.value == 'Deutschem Urheberrecht') {
|
|
showElement("divErstUrh");
|
|
showElement("divCommon");
|
|
showElement("mitteilungSection");
|
|
}
|
|
|
|
if (publishTypeSelection.value == 'Zweitveröffentlichung' && licenseTypeSelection.value == 'CC-Lizenz') {
|
|
showElement("divZweitveroeffentlichungOpenAccess");
|
|
showElement("divCommon");
|
|
showElement("erstVeroeffentlichtSection");
|
|
showElement("mitteilungSection");
|
|
}
|
|
|
|
if (publishTypeSelection.value == 'Zweitveröffentlichung' && licenseTypeSelection.value == 'Deutschem Urheberrecht') {
|
|
showElement("Select4A4B");
|
|
}
|
|
}
|
|
|
|
updateValidationStatus();
|
|
}
|
|
|
|
// Hilfsfunktion zum Anzeigen einer Sektion
|
|
function showSection(sectionId) {
|
|
const section = document.getElementById(sectionId);
|
|
if (section) {
|
|
section.style.display = 'block';
|
|
console.log('Sektion angezeigt:', sectionId);
|
|
} else {
|
|
console.warn('Sektion nicht gefunden:', sectionId);
|
|
}
|
|
}
|
|
|
|
// Funktion zum Verstecken aller Sektionen
|
|
function hideAllSections() {
|
|
const sectionsToHide = [
|
|
'divErstveroeffentlichungOpenAccess',
|
|
'divErstUrh',
|
|
'divZweitveroeffentlichungOpenAccess',
|
|
'divZweitUrh4A',
|
|
'divZweitUrh4B',
|
|
'divCommon',
|
|
'Select4A4B',
|
|
'erstVeroeffentlichtSection',
|
|
'mitteilungSection'
|
|
];
|
|
|
|
sectionsToHide.forEach(sectionId => {
|
|
const section = document.getElementById(sectionId);
|
|
if (section) {
|
|
section.style.display = 'none';
|
|
}
|
|
});
|
|
|
|
// Upload-Akkordeon deaktivieren
|
|
deactivateUploadAccordion();
|
|
}
|
|
|
|
// Funktion für die nächsten Schritte (4A/4B)
|
|
function showNextStep(version) {
|
|
// Verstecke beide 4A/4B Sektionen
|
|
document.getElementById('divZweitUrh4A').style.display = 'none';
|
|
document.getElementById('divZweitUrh4B').style.display = 'none';
|
|
|
|
// Zeige die entsprechende Sektion
|
|
if (version === 'Version4A') {
|
|
document.getElementById('divZweitUrh4A').style.display = 'block';
|
|
} else if (version === 'Version4B') {
|
|
document.getElementById('divZweitUrh4B').style.display = 'block';
|
|
}
|
|
|
|
showElement("divCommon");
|
|
showElement("erstVeroeffentlichtSection");
|
|
showElement("mitteilungSection");
|
|
|
|
updateValidationStatus();
|
|
}
|
|
|
|
// Validierungsstatus aktualisieren
|
|
function updateValidationStatus() {
|
|
|
|
// Nur sichtbare Checkboxen berücksichtigen
|
|
const allVisibleCheckboxes = getVisibleCheckboxes();
|
|
const checkedVisibleCheckboxes = allVisibleCheckboxes.filter(checkbox => checkbox.checked);
|
|
|
|
// Status aktualisieren - nur wenn sichtbare Checkboxen vorhanden sind
|
|
if (allVisibleCheckboxes.length === 0) {
|
|
// Keine sichtbaren Checkboxes - zeige neutralen Status
|
|
} else if (checkedVisibleCheckboxes.length === allVisibleCheckboxes.length) {
|
|
// Alle sichtbaren Checkboxes sind aktiviert
|
|
let i = checkCCLicenseSelection();
|
|
if (checkCCLicenseSelection() === true) {
|
|
//document.getElementById('finishContractSectionButton').disabled = false;
|
|
document.getElementById('statusTextContract').style.display = 'none';
|
|
activateUploadAccordion();
|
|
}
|
|
} else {
|
|
// Nicht alle sichtbaren Checkboxes sind aktiviert
|
|
document.getElementById('statusTextContract').style.display = 'block';
|
|
deactivateUploadAccordion();
|
|
}
|
|
}
|
|
|
|
// Funktion zum Finden aller sichtbaren Checkboxen
|
|
function getVisibleCheckboxes() {
|
|
const allCheckboxes = document.querySelectorAll('.validation-checkbox');
|
|
const visibleCheckboxes = [];
|
|
|
|
allCheckboxes.forEach(checkbox => {
|
|
// Prüfe ob das Checkbox-Element und seine Eltern sichtbar sind
|
|
if (isElementVisible(checkbox)) {
|
|
visibleCheckboxes.push(checkbox);
|
|
}
|
|
});
|
|
|
|
console.log('Sichtbare Checkboxes:', visibleCheckboxes.map(cb => cb.id || cb.name));
|
|
return visibleCheckboxes;
|
|
}
|
|
|
|
// Hilfsfunktion zur Überprüfung der Sichtbarkeit eines Elements
|
|
function isElementVisible(element) {
|
|
// Prüfe das Element selbst und alle Eltern-Container
|
|
let currentElement = element;
|
|
|
|
while (currentElement && currentElement !== document.body) {
|
|
const style = window.getComputedStyle(currentElement);
|
|
|
|
// Prüfe verschiedene CSS-Eigenschaften die Sichtbarkeit beeinflussen
|
|
if (style.display === 'none' ||
|
|
style.visibility === 'hidden' ||
|
|
style.opacity === '0' ||
|
|
currentElement.hidden) {
|
|
return false;
|
|
}
|
|
|
|
currentElement = currentElement.parentElement;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Debug-Funktion zum Testen der Element-Verfügbarkeit
|
|
function debugElements() {
|
|
|
|
return;
|
|
|
|
console.log('=== DEBUG ELEMENTS ===');
|
|
console.log('validation-info:', document.querySelector('.validation-info'));
|
|
console.log('validation-checkboxes:', document.querySelectorAll('.validation-checkbox'));
|
|
console.log('=====================');
|
|
}
|
|
|
|
// Prüfung, ob bei Zweitveröffentlichung unter CC-Lizenz genau eine Lizenz ausgewählt wurde, unter der die Publikation zuerst veröffentlicht wurde
|
|
|
|
function addCCLicenseValidation() {
|
|
const radioButtons = document.querySelectorAll('#checkCCLicense input[type="radio"][name="OAlicenseType"]');
|
|
|
|
radioButtons.forEach(radio => {
|
|
radio.addEventListener('change', function() {
|
|
const result = checkCCLicenseSelection();
|
|
console.log("Ergebnis checkCCLicenseSelection: " +result.message);
|
|
return result;
|
|
// Ggf. weitere Aktionen basierend auf der Validierung durchführen
|
|
// z.B. Fehlermeldungen anzeigen/verstecken
|
|
});
|
|
});
|
|
}
|
|
|
|
// Funktion zur Überprüfung, ob genau ein sichtbarer Radio-Button ausgewählt wurde
|
|
function checkCCLicenseSelection() {
|
|
// Alle Radio-Buttons innerhalb des checkCCLicense-Divs finden
|
|
const radioButtons = document.querySelectorAll('#checkCCLicense input[type="radio"][name="OAlicenseType"]');
|
|
|
|
// Zählen, wie viele sichtbare Radio-Buttons ausgewählt sind
|
|
let selectedCount = 0;
|
|
let selectedValue = null;
|
|
let visibleCount = 0;
|
|
let invisibleSelectedCount = 0;
|
|
let isValid = true;
|
|
|
|
radioButtons.forEach(radio => {
|
|
const isVisible = isElementVisible(radio);
|
|
|
|
if (isVisible) {
|
|
visibleCount++;
|
|
if (radio.checked) {
|
|
selectedCount++;
|
|
selectedValue = radio.value;
|
|
}
|
|
} else if (radio.checked) {
|
|
// Ausgewählter aber unsichtbarer Radio-Button
|
|
invisibleSelectedCount++;
|
|
}
|
|
});
|
|
|
|
// ist überhaupt eine Checkbox sichtbar? Wenn nein, return
|
|
if (visibleCount == 0)
|
|
return (isValid);
|
|
|
|
|
|
// Prüfen, ob genau einer der sichtbaren Radio-Buttons ausgewählt ist
|
|
isValid = selectedCount === 1 && invisibleSelectedCount === 0;
|
|
|
|
return (isValid);
|
|
|
|
/* return {
|
|
isValid: isValid,
|
|
selectedCount: selectedCount,
|
|
selectedValue: selectedValue,
|
|
visibleCount: visibleCount,
|
|
invisibleSelectedCount: invisibleSelectedCount,
|
|
message: isValid ?
|
|
`Gültige Auswahl: ${selectedValue}` :
|
|
selectedCount === 0 && invisibleSelectedCount === 0 ?
|
|
'Keine Lizenz ausgewählt' :
|
|
selectedCount > 1 ?
|
|
`Ungültig: ${selectedCount} sichtbare Lizenzen ausgewählt` :
|
|
invisibleSelectedCount > 0 ?
|
|
`Ungültig: ${invisibleSelectedCount} unsichtbare Radio-Buttons ausgewählt` :
|
|
'Ungültige Auswahl'
|
|
};
|
|
*/
|
|
}
|
|
|
|
// Verwendung beim Formular-Submit
|
|
function validateFormBeforeSubmit() {
|
|
const licenseCheck = checkCCLicenseSelection();
|
|
|
|
if (!licenseCheck.isValid) {
|
|
alert('Bitte wählen Sie eine Creative Commons Lizenz aus.');
|
|
return false; // Verhindert das Absenden des Formulars
|
|
}
|
|
|
|
console.log('Ausgewählte Lizenz:', licenseCheck.selectedValue);
|
|
return true; // Formular kann abgesendet werden
|
|
}
|
|
|
|
// Initialisierung nach dem Laden der Seite
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
addCCLicenseValidation();
|
|
});
|
|
|
|
|
|
// Alle required-Felder finden und prüfen
|
|
function validateRequiredFields() {
|
|
const requiredFields = document.querySelectorAll('[required]');
|
|
let allValid = true;
|
|
const emptyFields = [];
|
|
|
|
requiredFields.forEach(field => {
|
|
if (!field.value.trim()) {
|
|
allValid = false;
|
|
emptyFields.push(field.name || field.id);
|
|
}
|
|
});
|
|
|
|
// Spezialfall: hidden fields in uploadForm auswerten
|
|
let a = '';
|
|
|
|
if(a = document.getElementById('publicatedDocument')) {
|
|
console.log("hurray: publicatedDocument available" );
|
|
} else {
|
|
emptyFields.push('publicatedDocument');
|
|
console.log("publicatedDocument not available" );
|
|
}
|
|
|
|
if(a = document.getElementById('publicatedDocumentType')) {
|
|
console.log("hurray: publicatedDocumentType available" );
|
|
} else {
|
|
emptyFields.push('publicatedDocumentType');
|
|
console.log("publicatedDocumentType not available" );
|
|
}
|
|
|
|
|
|
if (!allValid) {
|
|
console.log('Leere Pflichtfelder:', emptyFields);
|
|
}
|
|
|
|
return emptyFields ;
|
|
}
|
|
|
|
// Prüfung wird in showSummary aufgerufen. Alternativ: bei Form-Submit prüfen
|
|
/*document.getElementById('VEROData').addEventListener('submit', function(e) {
|
|
if (!validateRequiredFields()) {
|
|
e.preventDefault();
|
|
alert('Bitte füllen Sie alle Pflichtfelder aus!');
|
|
}
|
|
});
|
|
*/
|
|
|
|
// Funktion zum Aktivieren des Upload-Accordions
|
|
function activateUploadAccordion() {
|
|
// Accordion-Container und Button finden
|
|
const accordionItem = document.getElementById('uploadData');
|
|
const accordionButton = accordionItem.querySelector('.accordion-button');
|
|
const accordionHeader = accordionItem.querySelector('h4');
|
|
|
|
// Inaktiv-Styling entfernen
|
|
accordionItem.classList.remove('opacity-50');
|
|
accordionButton.classList.remove('text-muted');
|
|
accordionButton.style.cursor = '';
|
|
|
|
// Button aktivieren
|
|
accordionButton.disabled = false;
|
|
|
|
// Bootstrap-Attribute für Collapse-Funktionalität hinzufügen
|
|
accordionButton.setAttribute('data-bs-toggle', 'collapse');
|
|
accordionButton.setAttribute('data-bs-target', '#collapseUpload');
|
|
|
|
// Inaktiv-Text entfernen (falls vorhanden)
|
|
const inactiveText = accordionHeader.querySelector('small.text-muted');
|
|
if (inactiveText) {
|
|
inactiveText.remove();
|
|
}
|
|
|
|
// Optional: Text zu "Aktiv" ändern oder einfach nur "Dateiupload" lassen
|
|
accordionHeader.innerHTML = 'Dateiupload';
|
|
|
|
console.log('Upload-Accordion wurde aktiviert');
|
|
}
|
|
|
|
// Funktion zum Deaktivieren des Upload-Accordions
|
|
function deactivateUploadAccordion() {
|
|
// Accordion-Container und Button finden
|
|
const accordionItem = document.getElementById('uploadData');
|
|
const accordionButton = accordionItem.querySelector('.accordion-button');
|
|
const accordionHeader = accordionItem.querySelector('h4');
|
|
const collapseElement = document.getElementById('collapseUpload');
|
|
|
|
// Accordion schließen falls geöffnet
|
|
if (collapseElement.classList.contains('show')) {
|
|
const bsCollapse = new bootstrap.Collapse(collapseElement);
|
|
bsCollapse.hide();
|
|
}
|
|
|
|
// Inaktiv-Styling hinzufügen
|
|
accordionItem.classList.add('opacity-50');
|
|
accordionButton.classList.add('text-muted');
|
|
accordionButton.style.cursor = 'not-allowed';
|
|
|
|
// Button deaktivieren
|
|
accordionButton.disabled = true;
|
|
|
|
// Bootstrap-Attribute entfernen
|
|
accordionButton.removeAttribute('data-bs-toggle');
|
|
accordionButton.removeAttribute('data-bs-target');
|
|
|
|
// Inaktiv-Text hinzufügen
|
|
accordionHeader.innerHTML = 'Dateiupload <span style="font-size:20px;" class="text-muted"> - erst nach dem Ausfüllen der Vertragssektion verfügbar</span>';
|
|
|
|
console.log('Upload-Accordion wurde deaktiviert');
|
|
}
|
|
|
|
// DOM Ready Event
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
deactivateUploadAccordion();
|
|
});
|
|
|
|
|
|
|