Merge pull request 'feat: add elsa form with a modular addition of content type' (#15) from dev into main
Reviewed-on: #15
This commit was merged in pull request #15.
This commit is contained in:
239
app/main.py
239
app/main.py
@@ -38,6 +38,12 @@ async def semesterapparat_form(request: Request):
|
||||
return templates.TemplateResponse("semesterapparat_form.html", {"request": request})
|
||||
|
||||
|
||||
@app.get("/elsa", response_class=HTMLResponse)
|
||||
async def elsa_form(request: Request):
|
||||
"""ELSA form page"""
|
||||
return templates.TemplateResponse("elsa_mono_form.html", {"request": request})
|
||||
|
||||
|
||||
@app.post("/submit")
|
||||
async def handle_form(
|
||||
request: Request,
|
||||
@@ -107,3 +113,236 @@ async def handle_form(
|
||||
print("=" * 80)
|
||||
|
||||
return RedirectResponse("/?success=true", status_code=303)
|
||||
|
||||
|
||||
@app.post("/elsa/submit")
|
||||
async def handle_elsa_form(request: Request):
|
||||
"""Handle ELSA form submission with multiple media types"""
|
||||
form_data = await request.form()
|
||||
|
||||
# Extract general information
|
||||
name = str(form_data.get("name", ""))
|
||||
lastname = str(form_data.get("lastname", ""))
|
||||
title_field = str(form_data.get("title", ""))
|
||||
mail = str(form_data.get("mail", ""))
|
||||
subject = str(form_data.get("subject", ""))
|
||||
classname = str(form_data.get("classname", ""))
|
||||
usage_date_from = str(form_data.get("usage_date_from", ""))
|
||||
usage_date_to = str(form_data.get("usage_date_to", ""))
|
||||
availability_date = str(form_data.get("availability_date", ""))
|
||||
message = str(form_data.get("message", ""))
|
||||
|
||||
# Basic email validation
|
||||
if not EMAIL_REGEX.match(mail):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Invalid email address format.",
|
||||
)
|
||||
|
||||
# Build XML structure
|
||||
root = Element("elsa_submission")
|
||||
|
||||
# General information
|
||||
general_info = SubElement(root, "general_info")
|
||||
SubElement(general_info, "name").text = name
|
||||
SubElement(general_info, "lastname").text = lastname
|
||||
SubElement(general_info, "title").text = title_field
|
||||
SubElement(general_info, "mail").text = mail
|
||||
SubElement(general_info, "subject").text = subject
|
||||
SubElement(general_info, "classname").text = classname
|
||||
SubElement(general_info, "usage_date_from").text = usage_date_from
|
||||
SubElement(general_info, "usage_date_to").text = usage_date_to
|
||||
SubElement(general_info, "availability_date").text = availability_date
|
||||
if message:
|
||||
SubElement(general_info, "message").text = message
|
||||
|
||||
# Process media sections
|
||||
media_root = SubElement(root, "media")
|
||||
|
||||
# Process Monografie entries
|
||||
if "monografie_author[]" in form_data:
|
||||
monografie_authors = [str(v) for v in form_data.getlist("monografie_author[]")]
|
||||
monografie_years = [str(v) for v in form_data.getlist("monografie_year[]")]
|
||||
monografie_editions = [
|
||||
str(v) for v in form_data.getlist("monografie_edition[]")
|
||||
]
|
||||
monografie_titles = [str(v) for v in form_data.getlist("monografie_title[]")]
|
||||
monografie_signatures = [
|
||||
str(v) for v in form_data.getlist("monografie_signature[]")
|
||||
]
|
||||
monografie_pages_from = [
|
||||
str(v) for v in form_data.getlist("monografie_pages_from[]")
|
||||
]
|
||||
monografie_pages_to = [
|
||||
str(v) for v in form_data.getlist("monografie_pages_to[]")
|
||||
]
|
||||
|
||||
# Get section IDs from the form (assuming they're in data-section attributes)
|
||||
# Since we can't directly access data-section from form_data, we'll process sequentially
|
||||
monografie_section = SubElement(media_root, "monografien")
|
||||
for i in range(len(monografie_authors)):
|
||||
entry = SubElement(monografie_section, "entry")
|
||||
SubElement(entry, "author").text = (
|
||||
monografie_authors[i] if i < len(monografie_authors) else ""
|
||||
)
|
||||
SubElement(entry, "year").text = (
|
||||
monografie_years[i] if i < len(monografie_years) else ""
|
||||
)
|
||||
SubElement(entry, "edition").text = (
|
||||
monografie_editions[i] if i < len(monografie_editions) else ""
|
||||
)
|
||||
SubElement(entry, "title").text = (
|
||||
monografie_titles[i] if i < len(monografie_titles) else ""
|
||||
)
|
||||
SubElement(entry, "signature").text = (
|
||||
monografie_signatures[i] if i < len(monografie_signatures) else ""
|
||||
)
|
||||
SubElement(entry, "pages_from").text = (
|
||||
monografie_pages_from[i] if i < len(monografie_pages_from) else ""
|
||||
)
|
||||
SubElement(entry, "pages_to").text = (
|
||||
monografie_pages_to[i] if i < len(monografie_pages_to) else ""
|
||||
)
|
||||
|
||||
# Process Zeitschriftenartikel entries
|
||||
if "zeitschrift_author[]" in form_data:
|
||||
zeitschrift_authors = [
|
||||
str(v) for v in form_data.getlist("zeitschrift_author[]")
|
||||
]
|
||||
zeitschrift_years = [str(v) for v in form_data.getlist("zeitschrift_year[]")]
|
||||
zeitschrift_volumes = [
|
||||
str(v) for v in form_data.getlist("zeitschrift_volume[]")
|
||||
]
|
||||
zeitschrift_article_titles = [
|
||||
str(v) for v in form_data.getlist("zeitschrift_article_title[]")
|
||||
]
|
||||
zeitschrift_journal_titles = [
|
||||
str(v) for v in form_data.getlist("zeitschrift_journal_title[]")
|
||||
]
|
||||
zeitschrift_signatures = [
|
||||
str(v) for v in form_data.getlist("zeitschrift_signature[]")
|
||||
]
|
||||
zeitschrift_pages_from = [
|
||||
str(v) for v in form_data.getlist("zeitschrift_pages_from[]")
|
||||
]
|
||||
zeitschrift_pages_to = [
|
||||
str(v) for v in form_data.getlist("zeitschrift_pages_to[]")
|
||||
]
|
||||
|
||||
zeitschrift_section = SubElement(media_root, "zeitschriftenartikel")
|
||||
for i in range(len(zeitschrift_authors)):
|
||||
entry = SubElement(zeitschrift_section, "entry")
|
||||
SubElement(entry, "author").text = (
|
||||
zeitschrift_authors[i] if i < len(zeitschrift_authors) else ""
|
||||
)
|
||||
SubElement(entry, "year").text = (
|
||||
zeitschrift_years[i] if i < len(zeitschrift_years) else ""
|
||||
)
|
||||
SubElement(entry, "volume").text = (
|
||||
zeitschrift_volumes[i] if i < len(zeitschrift_volumes) else ""
|
||||
)
|
||||
SubElement(entry, "article_title").text = (
|
||||
zeitschrift_article_titles[i]
|
||||
if i < len(zeitschrift_article_titles)
|
||||
else ""
|
||||
)
|
||||
SubElement(entry, "journal_title").text = (
|
||||
zeitschrift_journal_titles[i]
|
||||
if i < len(zeitschrift_journal_titles)
|
||||
else ""
|
||||
)
|
||||
SubElement(entry, "signature").text = (
|
||||
zeitschrift_signatures[i] if i < len(zeitschrift_signatures) else ""
|
||||
)
|
||||
SubElement(entry, "pages_from").text = (
|
||||
zeitschrift_pages_from[i] if i < len(zeitschrift_pages_from) else ""
|
||||
)
|
||||
SubElement(entry, "pages_to").text = (
|
||||
zeitschrift_pages_to[i] if i < len(zeitschrift_pages_to) else ""
|
||||
)
|
||||
|
||||
# Process Herausgeberwerk entries
|
||||
if "herausgeber_publisher[]" in form_data:
|
||||
herausgeber_publishers = [
|
||||
str(v) for v in form_data.getlist("herausgeber_publisher[]")
|
||||
]
|
||||
herausgeber_work_titles = [
|
||||
str(v) for v in form_data.getlist("herausgeber_work_title[]")
|
||||
]
|
||||
herausgeber_years = [str(v) for v in form_data.getlist("herausgeber_year[]")]
|
||||
herausgeber_editions = [
|
||||
str(v) for v in form_data.getlist("herausgeber_edition[]")
|
||||
]
|
||||
herausgeber_article_authors = [
|
||||
str(v) for v in form_data.getlist("herausgeber_article_author[]")
|
||||
]
|
||||
herausgeber_article_titles = [
|
||||
str(v) for v in form_data.getlist("herausgeber_article_title[]")
|
||||
]
|
||||
herausgeber_signatures = [
|
||||
str(v) for v in form_data.getlist("herausgeber_signature[]")
|
||||
]
|
||||
herausgeber_pages_from = [
|
||||
str(v) for v in form_data.getlist("herausgeber_pages_from[]")
|
||||
]
|
||||
herausgeber_pages_to = [
|
||||
str(v) for v in form_data.getlist("herausgeber_pages_to[]")
|
||||
]
|
||||
|
||||
herausgeber_section = SubElement(media_root, "herausgeberwerke")
|
||||
for i in range(len(herausgeber_publishers)):
|
||||
entry = SubElement(herausgeber_section, "entry")
|
||||
SubElement(entry, "publisher").text = (
|
||||
herausgeber_publishers[i] if i < len(herausgeber_publishers) else ""
|
||||
)
|
||||
SubElement(entry, "work_title").text = (
|
||||
herausgeber_work_titles[i] if i < len(herausgeber_work_titles) else ""
|
||||
)
|
||||
SubElement(entry, "year").text = (
|
||||
herausgeber_years[i] if i < len(herausgeber_years) else ""
|
||||
)
|
||||
SubElement(entry, "edition").text = (
|
||||
herausgeber_editions[i] if i < len(herausgeber_editions) else ""
|
||||
)
|
||||
SubElement(entry, "article_author").text = (
|
||||
herausgeber_article_authors[i]
|
||||
if i < len(herausgeber_article_authors)
|
||||
else ""
|
||||
)
|
||||
SubElement(entry, "article_title").text = (
|
||||
herausgeber_article_titles[i]
|
||||
if i < len(herausgeber_article_titles)
|
||||
else ""
|
||||
)
|
||||
SubElement(entry, "signature").text = (
|
||||
herausgeber_signatures[i] if i < len(herausgeber_signatures) else ""
|
||||
)
|
||||
SubElement(entry, "pages_from").text = (
|
||||
herausgeber_pages_from[i] if i < len(herausgeber_pages_from) else ""
|
||||
)
|
||||
SubElement(entry, "pages_to").text = (
|
||||
herausgeber_pages_to[i] if i < len(herausgeber_pages_to) else ""
|
||||
)
|
||||
|
||||
xml_data = tostring(root, encoding="unicode")
|
||||
|
||||
# Send or print email
|
||||
msg = MIMEText(xml_data, "xml")
|
||||
msg["Subject"] = "New ELSA Form Submission"
|
||||
msg["From"] = MAIL_FROM
|
||||
msg["To"] = MAIL_TO
|
||||
|
||||
if MAIL_ENABLED:
|
||||
with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
|
||||
server.send_message(msg)
|
||||
else:
|
||||
print("=" * 80)
|
||||
print("MAIL SENDING DISABLED - Would have sent:")
|
||||
print(f"From: {MAIL_FROM}")
|
||||
print(f"To: {MAIL_TO}")
|
||||
print(f"Subject: {msg['Subject']}")
|
||||
print("-" * 80)
|
||||
print(xml_data)
|
||||
print("=" * 80)
|
||||
|
||||
return RedirectResponse("/?success=true", status_code=303)
|
||||
|
||||
@@ -598,3 +598,130 @@ input[type="radio"] { accent-color: var(--control-accent); }
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* ELSA specific styles */
|
||||
.legal-notice {
|
||||
background: #eff6ff;
|
||||
border: 1px solid #93c5fd;
|
||||
border-radius: 12px;
|
||||
padding: 16px 20px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .legal-notice {
|
||||
background: #0f2942;
|
||||
border-color: #1e3a52;
|
||||
}
|
||||
|
||||
.legal-notice h3 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 0 0 8px;
|
||||
font-size: 1rem;
|
||||
color: #1e40af;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .legal-notice h3 {
|
||||
color: #93c5fd;
|
||||
}
|
||||
|
||||
.legal-notice p {
|
||||
margin: 0;
|
||||
line-height: 1.6;
|
||||
font-size: 0.95rem;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.media-controls {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.media-section {
|
||||
background: var(--table-head-bg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.media-section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.media-section-header h3 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 0;
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--card-bg);
|
||||
color: var(--text);
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease, color 0.2s ease;
|
||||
}
|
||||
|
||||
.btn-icon:hover {
|
||||
background: var(--table-head-bg);
|
||||
color: #ef4444;
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
font-size: 0.9rem;
|
||||
padding: 8px 14px;
|
||||
}
|
||||
|
||||
.media-table {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.media-table th {
|
||||
font-size: 0.85rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.media-table td {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
.media-table input[type="text"],
|
||||
.media-table input[type="number"] {
|
||||
font-size: 0.9rem;
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
.media-table input[type="number"] {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.media-controls {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.media-table {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.media-table th,
|
||||
.media-table td {
|
||||
padding: 6px 8px;
|
||||
}
|
||||
}
|
||||
|
||||
310
app/templates/elsa_mono_form.html
Normal file
310
app/templates/elsa_mono_form.html
Normal file
@@ -0,0 +1,310 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ELSA - Elektronischer Semesterapparat</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" href="/static/styles.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@7.4.47/css/materialdesignicons.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<div class="header-left">
|
||||
<img class="logo" src="https://www.ph-freiburg.de/_assets/cc3dd7db45300ecc1f3aeed85bda5532/Images/logo-big-blue.svg" alt="PH Freiburg Logo" />
|
||||
<div class="brand">
|
||||
<div class="brand-title">Bibliothek der Pädagogischen Hochschule Freiburg</div>
|
||||
<div class="brand-sub">Hochschulbibliothek · ELSA</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" id="theme-toggle" class="theme-toggle" aria-label="Switch to dark mode" title="Switch to dark mode">
|
||||
<span class="mdi mdi-theme-light-dark" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<section class="card">
|
||||
<h1>ELSA - Elektronischer Semesterapparat</h1>
|
||||
|
||||
<div class="legal-notice">
|
||||
<h3><span class="mdi mdi-information"></span> Rechtlicher Hinweis</h3>
|
||||
<p>
|
||||
Das Urheberrecht gestattet gemäß § 60a UrhG zur Veranschaulichung des Unterrichts die Bereitstellung elektronischer Kopien bis max. 15% von veröffentlichten Werken, von einzelnen Aufsätzen aus Fachzeitschriften und von Werken geringen Umfangs (max. 25 S. Gesamtumfang) für einen genau abgegrenzten Benutzerkreis wie den Teilnehmenden einer Lehrveranstaltung, die sich auf ILIAS angemeldet haben.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form method="post" action="/elsa/submit" class="request-form">
|
||||
<h2>Allgemeine Informationen</h2>
|
||||
<div class="grid-form">
|
||||
<div class="form-field">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" name="name" id="name" required>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="lastname">Nachname</label>
|
||||
<input type="text" name="lastname" id="lastname" required>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="title">Titel (optional)</label>
|
||||
<input type="text" name="title" id="title">
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="mail">Email</label>
|
||||
<input type="email" name="mail" id="mail" required>
|
||||
</div>
|
||||
|
||||
<div class="form-field">
|
||||
<label for="subject">Fach</label>
|
||||
<select name="subject" id="subject" required>
|
||||
<option value="">-- Auswählen --</option>
|
||||
<option>Biologie</option>
|
||||
<option>Chemie</option>
|
||||
<option>Deutsch</option>
|
||||
<option>Englisch</option>
|
||||
<option>Erziehungswirtschaft</option>
|
||||
<option>Französisch</option>
|
||||
<option>Geographie</option>
|
||||
<option>Geschichte</option>
|
||||
<option>Gesundheitspädagogik</option>
|
||||
<option>Haushalt / Textil</option>
|
||||
<option>Kunst</option>
|
||||
<option>Mathematik / Informatik</option>
|
||||
<option>Medien in der Bildung</option>
|
||||
<option>Musik</option>
|
||||
<option>Philosophie</option>
|
||||
<option>Physik</option>
|
||||
<option>Politikwissenschaft</option>
|
||||
<option>Prorektorat Lehre und Studium</option>
|
||||
<option>Psychologie</option>
|
||||
<option>Soziologie</option>
|
||||
<option>Sport</option>
|
||||
<option>Technik</option>
|
||||
<option>Theologie</option>
|
||||
<option>Wirtschaftslehre</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="classname">Lehrveranstaltungsname</label>
|
||||
<input type="text" name="classname" id="classname" required>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="usage_date_from">Nutzungszeitraum von</label>
|
||||
<input type="date" name="usage_date_from" id="usage_date_from" required>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="usage_date_to">Nutzungszeitraum bis</label>
|
||||
<input type="date" name="usage_date_to" id="usage_date_to" required>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="availability_date">Bereitstellungsdatum</label>
|
||||
<input type="date" name="availability_date" id="availability_date" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Medien</h2>
|
||||
<div class="media-controls">
|
||||
<button type="button" class="btn btn-secondary" onclick="addMediaType('monografie')">
|
||||
<span class="mdi mdi-book"></span> + Monografie
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary" onclick="addMediaType('zeitschriftenartikel')">
|
||||
<span class="mdi mdi-newspaper"></span> + Zeitschriftenartikel
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary" onclick="addMediaType('herausgeberwerk')">
|
||||
<span class="mdi mdi-book-multiple"></span> + Herausgeberwerk
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="media-sections"></div>
|
||||
|
||||
<div class="form-field" style="margin-top: 20px;">
|
||||
<label for="message">Nachricht (optional)</label>
|
||||
<textarea name="message" id="message" rows="4" placeholder="Zusätzliche Anmerkungen oder Hinweise..."></textarea>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button type="submit" class="btn btn-primary">Absenden</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
let mediaCounter = {
|
||||
monografie: 0,
|
||||
zeitschriftenartikel: 0,
|
||||
herausgeberwerk: 0
|
||||
};
|
||||
|
||||
let sectionCounter = 0;
|
||||
|
||||
// Theme toggle functionality (in IIFE to avoid polluting global scope)
|
||||
(function() {
|
||||
const STORAGE_KEY = 'theme';
|
||||
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const saved = localStorage.getItem(STORAGE_KEY);
|
||||
|
||||
function setTheme(theme) {
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
localStorage.setItem(STORAGE_KEY, theme);
|
||||
const btn = document.getElementById('theme-toggle');
|
||||
if (btn) {
|
||||
const label = theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode';
|
||||
btn.setAttribute('aria-label', label);
|
||||
btn.title = label;
|
||||
}
|
||||
}
|
||||
|
||||
setTheme(saved || (prefersDark ? 'dark' : 'light'));
|
||||
|
||||
const btn = document.getElementById('theme-toggle');
|
||||
if (btn) {
|
||||
btn.addEventListener('click', () => {
|
||||
const current = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light';
|
||||
setTheme(current === 'dark' ? 'light' : 'dark');
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
// Media management functions (global scope for onclick handlers)
|
||||
function addMediaType(type) {
|
||||
const container = document.getElementById('media-sections');
|
||||
const sectionId = 'section-' + sectionCounter++;
|
||||
|
||||
const section = document.createElement('div');
|
||||
section.className = 'media-section';
|
||||
section.id = sectionId;
|
||||
section.setAttribute('data-type', type);
|
||||
|
||||
let title = '';
|
||||
let tableHtml = '';
|
||||
|
||||
if (type === 'monografie') {
|
||||
title = 'Monografie';
|
||||
tableHtml = '<table class="data-table media-table" id="table-' + sectionId + '">' +
|
||||
'<tr>' +
|
||||
'<th>Autor (Nachname, Vorname)</th>' +
|
||||
'<th>Jahr</th>' +
|
||||
'<th>Auflage</th>' +
|
||||
'<th>Titel</th>' +
|
||||
'<th>Signatur</th>' +
|
||||
'<th>Seiten von</th>' +
|
||||
'<th>Seiten bis</th>' +
|
||||
'<th></th>' +
|
||||
'</tr>' +
|
||||
'</table>';
|
||||
} else if (type === 'zeitschriftenartikel') {
|
||||
title = 'Zeitschriftenartikel';
|
||||
tableHtml = '<table class="data-table media-table" id="table-' + sectionId + '">' +
|
||||
'<tr>' +
|
||||
'<th>Autor (Nachname, Vorname)</th>' +
|
||||
'<th>Jahr</th>' +
|
||||
'<th>Band</th>' +
|
||||
'<th>Titel des Artikels</th>' +
|
||||
'<th>Titel der Zeitschrift</th>' +
|
||||
'<th>Signatur</th>' +
|
||||
'<th>Seiten von</th>' +
|
||||
'<th>Seiten bis</th>' +
|
||||
'<th></th>' +
|
||||
'</tr>' +
|
||||
'</table>';
|
||||
} else if (type === 'herausgeberwerk') {
|
||||
title = 'Herausgeberwerk';
|
||||
tableHtml = '<table class="data-table media-table" id="table-' + sectionId + '">' +
|
||||
'<tr>' +
|
||||
'<th>Herausgeber (Nachname, Vorname)</th>' +
|
||||
'<th>Titel des Werks</th>' +
|
||||
'<th>Jahr</th>' +
|
||||
'<th>Auflage</th>' +
|
||||
'<th>Autor des Artikels (Nachname, Vorname)</th>' +
|
||||
'<th>Titel des Artikels</th>' +
|
||||
'<th>Signatur</th>' +
|
||||
'<th>Seiten von</th>' +
|
||||
'<th>Seiten bis</th>' +
|
||||
'<th></th>' +
|
||||
'</tr>' +
|
||||
'</table>';
|
||||
}
|
||||
|
||||
section.innerHTML = '<div class="media-section-header">' +
|
||||
'<h3><span class="mdi ' + getIconForType(type) + '"></span> ' + title + '</h3>' +
|
||||
'<button type="button" class="btn-icon" onclick="removeMediaSection(\'' + sectionId + '\')" title="Sektion entfernen">' +
|
||||
'<span class="mdi mdi-close"></span>' +
|
||||
'</button>' +
|
||||
'</div>' +
|
||||
tableHtml +
|
||||
'<button type="button" class="btn btn-secondary btn-sm" onclick="addMediaRow(\'' + sectionId + '\', \'' + type + '\')">' +
|
||||
'+ Eintrag hinzufügen' +
|
||||
'</button>';
|
||||
|
||||
container.appendChild(section);
|
||||
|
||||
// Add first row automatically
|
||||
addMediaRow(sectionId, type);
|
||||
}
|
||||
|
||||
function getIconForType(type) {
|
||||
const icons = {
|
||||
'monografie': 'mdi-book',
|
||||
'zeitschriftenartikel': 'mdi-newspaper',
|
||||
'herausgeberwerk': 'mdi-book-multiple'
|
||||
};
|
||||
return icons[type] || 'mdi-file';
|
||||
}
|
||||
|
||||
function addMediaRow(sectionId, type) {
|
||||
const table = document.getElementById('table-' + sectionId);
|
||||
const row = table.insertRow(-1);
|
||||
const rowId = sectionId + '-row-' + mediaCounter[type]++;
|
||||
row.id = rowId;
|
||||
|
||||
if (type === 'monografie') {
|
||||
row.innerHTML = '<td><input type="text" name="monografie_author[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="monografie_year[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="monografie_edition[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="monografie_title[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="monografie_signature[]" data-section="' + sectionId + '" placeholder="Optional"></td>' +
|
||||
'<td><input type="number" name="monografie_pages_from[]" data-section="' + sectionId + '" required min="1"></td>' +
|
||||
'<td><input type="number" name="monografie_pages_to[]" data-section="' + sectionId + '" required min="1"></td>' +
|
||||
'<td><button type="button" class="btn-icon" onclick="removeRow(\'' + rowId + '\')" title="Zeile entfernen"><span class="mdi mdi-delete"></span></button></td>';
|
||||
} else if (type === 'zeitschriftenartikel') {
|
||||
row.innerHTML = '<td><input type="text" name="zeitschrift_author[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="zeitschrift_year[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="zeitschrift_volume[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="zeitschrift_article_title[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="zeitschrift_journal_title[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="zeitschrift_signature[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="number" name="zeitschrift_pages_from[]" data-section="' + sectionId + '" required min="1"></td>' +
|
||||
'<td><input type="number" name="zeitschrift_pages_to[]" data-section="' + sectionId + '" required min="1"></td>' +
|
||||
'<td><button type="button" class="btn-icon" onclick="removeRow(\'' + rowId + '\')" title="Zeile entfernen"><span class="mdi mdi-delete"></span></button></td>';
|
||||
} else if (type === 'herausgeberwerk') {
|
||||
row.innerHTML = '<td><input type="text" name="herausgeber_publisher[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="herausgeber_work_title[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="herausgeber_year[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="herausgeber_edition[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="herausgeber_article_author[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="herausgeber_article_title[]" data-section="' + sectionId + '" required></td>' +
|
||||
'<td><input type="text" name="herausgeber_signature[]" data-section="' + sectionId + '" placeholder="Optional"></td>' +
|
||||
'<td><input type="number" name="herausgeber_pages_from[]" data-section="' + sectionId + '" required min="1"></td>' +
|
||||
'<td><input type="number" name="herausgeber_pages_to[]" data-section="' + sectionId + '" required min="1"></td>' +
|
||||
'<td><button type="button" class="btn-icon" onclick="removeRow(\'' + rowId + '\')" title="Zeile entfernen"><span class="mdi mdi-delete"></span></button></td>';
|
||||
}
|
||||
}
|
||||
|
||||
function removeRow(rowId) {
|
||||
const row = document.getElementById(rowId);
|
||||
if (row) {
|
||||
row.remove();
|
||||
}
|
||||
}
|
||||
|
||||
function removeMediaSection(sectionId) {
|
||||
const section = document.getElementById(sectionId);
|
||||
if (section) {
|
||||
if (confirm('Möchten Sie diese Sektion wirklich entfernen?')) {
|
||||
section.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -40,16 +40,16 @@
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="service-card service-card-disabled" onclick="showConstructionWarning()">
|
||||
<a href="/elsa" class="service-card">
|
||||
<div class="service-icon">
|
||||
<span class="mdi mdi-library-shelves"></span>
|
||||
</div>
|
||||
<h2>ELSA</h2>
|
||||
<p>Elektronischer Semesterapparat</p>
|
||||
<div class="service-badge">
|
||||
<span class="mdi mdi-hammer-wrench"></span> Im Aufbau
|
||||
</div>
|
||||
<div class="service-arrow">
|
||||
<span class="mdi mdi-arrow-right"></span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<section class="info-section">
|
||||
|
||||
Reference in New Issue
Block a user