Initial bundle implementation
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/themes/dark.css">
|
||||
|
||||
<div class="eventlist-layout">
|
||||
<div class="eventlist-sidebar">
|
||||
<form method="get" id="event-filter-form">
|
||||
<h3>Filtern</h3>
|
||||
<input type="hidden" name="archive_filter_applied" value="1">
|
||||
|
||||
{% if availableArchives is not empty %}
|
||||
<fieldset>
|
||||
<legend>Event-Archive</legend>
|
||||
|
||||
{% for archive in availableArchives %}
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="archive_ids[]"
|
||||
value="{{ archive.id }}"
|
||||
class="archive-filter-checkbox"
|
||||
{% if archive.id in selectedArchiveIds %}checked{% endif %}
|
||||
>
|
||||
{{ archive.title }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
{% endif %}
|
||||
|
||||
<label for="filter-from-input">
|
||||
<span>Von</span>
|
||||
</label>
|
||||
<div class="flatpickr" id="filter-from-wrap">
|
||||
<input id="filter-from-input" type="text" name="from" value="{{ from }}" autocomplete="off" data-input>
|
||||
<a id="filter-from-clear" class="input-button" title="clear" data-clear {% if from is empty %}hidden{% endif %}>×</a>
|
||||
</div>
|
||||
|
||||
<label for="filter-to-input">
|
||||
<span>Bis</span>
|
||||
</label>
|
||||
<div class="flatpickr" id="filter-to-wrap">
|
||||
<input id="filter-to-input" type="text" name="to" value="{{ to }}" autocomplete="off" data-input>
|
||||
<a id="filter-to-clear" class="input-button" title="clear" data-clear {% if to is empty %}hidden{% endif %}>×</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form method="post" action="/events/pdf" id="pdf-export-form">
|
||||
<input type="hidden" name="from" value="{{ from }}">
|
||||
<input type="hidden" name="to" value="{{ to }}">
|
||||
|
||||
{% if pdfError == 'no_selection' %}
|
||||
<p>Bitte wählen Sie mindestens einen Termin für den PDF-Export aus.</p>
|
||||
{% elseif pdfError == 'not_found' %}
|
||||
<p>Die ausgewählten Termine konnten nicht geladen werden.</p>
|
||||
{% endif %}
|
||||
|
||||
<p id="pdf-selection-error" role="alert" aria-live="polite" hidden>Bitte wählen Sie mindestens einen Termin für den PDF-Export aus.</p>
|
||||
|
||||
<p>
|
||||
<label for="pdf_heading">Überschrift (optional)</label>
|
||||
<input id="pdf_heading" type="text" name="pdf_heading" value="">
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="pdf_intro">Einleitungstext (optional)</label>
|
||||
<textarea id="pdf_intro" name="pdf_intro" rows="4"></textarea>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<button type="submit">PDF erstellen</button>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="eventlist-results">
|
||||
{% if events is not empty %}
|
||||
<p>
|
||||
<label>
|
||||
<input type="checkbox" id="select-all-events">
|
||||
Alle auswählen
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
{% for event in events %}
|
||||
<li class="pid-{{ event.pid }}{% if event.isFeatured %} is-featured{% endif %}">
|
||||
<label>
|
||||
<input type="checkbox" name="event_ids[]" value="{{ event.id }}" class="event-select-checkbox" form="pdf-export-form">
|
||||
{{ event.title }}
|
||||
</label>
|
||||
|
||||
<p>
|
||||
{{ event.startDate }}{% if event.endDate %} - {{ event.endDate }}{% endif %}
|
||||
</p>
|
||||
|
||||
{% if event.url %}
|
||||
<a href="{{ event.url }}">weiterlesen…</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p>Keine Termine gefunden.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/de.js"></script>
|
||||
<script>
|
||||
(function () {
|
||||
const filterForm = document.getElementById('event-filter-form');
|
||||
const filterFromWrap = document.getElementById('filter-from-wrap');
|
||||
const filterToWrap = document.getElementById('filter-to-wrap');
|
||||
const filterFromInput = document.getElementById('filter-from-input');
|
||||
const filterToInput = document.getElementById('filter-to-input');
|
||||
const filterFromClear = document.getElementById('filter-from-clear');
|
||||
const filterToClear = document.getElementById('filter-to-clear');
|
||||
const archiveFilterCheckboxes = document.querySelectorAll('.archive-filter-checkbox');
|
||||
|
||||
if (filterForm && filterFromInput && filterToInput) {
|
||||
const submitFilterForm = function () {
|
||||
filterForm.submit();
|
||||
};
|
||||
|
||||
const updateClearButtons = function () {
|
||||
if (filterFromClear) {
|
||||
filterFromClear.hidden = filterFromInput.value === '';
|
||||
}
|
||||
|
||||
if (filterToClear) {
|
||||
filterToClear.hidden = filterToInput.value === '';
|
||||
}
|
||||
};
|
||||
|
||||
updateClearButtons();
|
||||
|
||||
if (typeof flatpickr === 'function') {
|
||||
const commonConfig = {
|
||||
wrap: true,
|
||||
dateFormat: 'Y-m-d',
|
||||
allowInput: true,
|
||||
locale: (window.flatpickr && window.flatpickr.l10ns && window.flatpickr.l10ns.de) ? window.flatpickr.l10ns.de : 'default',
|
||||
onChange: [
|
||||
function () {
|
||||
updateClearButtons();
|
||||
submitFilterForm();
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
if (filterFromWrap) {
|
||||
flatpickr(filterFromWrap, commonConfig);
|
||||
}
|
||||
|
||||
if (filterToWrap) {
|
||||
flatpickr(filterToWrap, commonConfig);
|
||||
}
|
||||
|
||||
filterFromInput.addEventListener('input', function () {
|
||||
updateClearButtons();
|
||||
|
||||
if (filterFromInput.value === '') {
|
||||
submitFilterForm();
|
||||
}
|
||||
});
|
||||
|
||||
filterToInput.addEventListener('input', function () {
|
||||
updateClearButtons();
|
||||
|
||||
if (filterToInput.value === '') {
|
||||
submitFilterForm();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
filterFromInput.addEventListener('change', function () {
|
||||
updateClearButtons();
|
||||
submitFilterForm();
|
||||
});
|
||||
|
||||
filterToInput.addEventListener('change', function () {
|
||||
updateClearButtons();
|
||||
submitFilterForm();
|
||||
});
|
||||
}
|
||||
|
||||
if (filterFromClear) {
|
||||
filterFromClear.addEventListener('click', function () {
|
||||
window.setTimeout(updateClearButtons, 0);
|
||||
});
|
||||
}
|
||||
|
||||
if (filterToClear) {
|
||||
filterToClear.addEventListener('click', function () {
|
||||
window.setTimeout(updateClearButtons, 0);
|
||||
});
|
||||
}
|
||||
|
||||
archiveFilterCheckboxes.forEach(function (checkbox) {
|
||||
checkbox.addEventListener('change', submitFilterForm);
|
||||
});
|
||||
}
|
||||
|
||||
const selectAll = document.getElementById('select-all-events');
|
||||
|
||||
if (!selectAll) {
|
||||
return;
|
||||
}
|
||||
|
||||
const eventCheckboxes = document.querySelectorAll('.event-select-checkbox');
|
||||
const exportForm = document.getElementById('pdf-export-form');
|
||||
const selectionError = document.getElementById('pdf-selection-error');
|
||||
|
||||
selectAll.addEventListener('change', function () {
|
||||
eventCheckboxes.forEach(function (checkbox) {
|
||||
checkbox.checked = selectAll.checked;
|
||||
});
|
||||
});
|
||||
|
||||
eventCheckboxes.forEach(function (checkbox) {
|
||||
checkbox.addEventListener('change', function () {
|
||||
const allChecked = Array.from(eventCheckboxes).every(function (item) {
|
||||
return item.checked;
|
||||
});
|
||||
|
||||
selectAll.checked = allChecked;
|
||||
|
||||
if (selectionError && checkbox.checked) {
|
||||
selectionError.hidden = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (exportForm) {
|
||||
exportForm.addEventListener('submit', function (event) {
|
||||
const anyChecked = Array.from(eventCheckboxes).some(function (item) {
|
||||
return item.checked;
|
||||
});
|
||||
|
||||
if (!anyChecked) {
|
||||
event.preventDefault();
|
||||
|
||||
if (selectionError) {
|
||||
selectionError.hidden = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
@@ -0,0 +1,70 @@
|
||||
<style>
|
||||
body {
|
||||
font-family: DejaVu Sans, sans-serif;
|
||||
font-size: 11pt;
|
||||
line-height: 1.4;
|
||||
margin: 1.3cm 1.2cm 1.2cm 1.2cm;
|
||||
}
|
||||
|
||||
.event-time {
|
||||
color: #666;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 0 0.55cm 0;
|
||||
}
|
||||
|
||||
.pdf-title {
|
||||
max-width: 70%;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 0.38cm 0;
|
||||
}
|
||||
|
||||
.event-list {
|
||||
margin: 0.45cm 0 0 0;
|
||||
}
|
||||
|
||||
.event-item {
|
||||
margin: 0 0 0.18cm 0;
|
||||
}
|
||||
|
||||
.pdf-logo {
|
||||
position: absolute;
|
||||
top: 0.3cm;
|
||||
right: 1.3cm;
|
||||
width: 2.4cm;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
{% if logoDataUri %}
|
||||
<img src="{{ logoDataUri }}" alt="Gymnasium Nossen" class="pdf-logo">
|
||||
{% endif %}
|
||||
|
||||
<h1 class="pdf-title">{{ heading }}</h1>
|
||||
|
||||
{% if introText %}
|
||||
<p>{{ introText }}</p>
|
||||
{% endif %}
|
||||
|
||||
{% if dateRange %}
|
||||
<p>{{ dateRange }}</p>
|
||||
{% endif %}
|
||||
|
||||
<div class="event-list">
|
||||
{% for event in events %}
|
||||
<p class="event-item">
|
||||
{{ event.title }} –
|
||||
<span class="event-time">
|
||||
{{ event.startText }}
|
||||
{% if event.endText %}
|
||||
- {{ event.endText }}
|
||||
{% endif %}
|
||||
</span>
|
||||
</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
Reference in New Issue
Block a user