Files
EIS/mod_pdf_tree/tmpl/default.php
Thomas Spohr fc1de065c9 Mit Formular
2025-08-20 14:08:20 +02:00

241 lines
7.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php defined('_JEXEC') or die; ?>
<style>
/* =========================
Layout-Container
========================= */
.pdf-tree-wrapper {
display: flex;
align-items: stretch; /* wichtig für scrollende Kinder */
gap: 1em;
background: #f9f9f9;
padding: 1em;
border: 1px solid #ddd;
border-radius: 6px;
box-shadow: 0 4px 10px rgba(0,0,0,0.05);
min-height: 0; /* erlaubt Overflow in Flex-Kindern */
}
/* Linke Spalte: Baum */
.pdf-tree-container {
flex: 0 0 30%;
max-height: calc(var(--vh, 100vh) - 160px); /* robust auf Desktop/iPad */
overflow: auto;
-webkit-overflow-scrolling: touch; /* smooth scroll iOS */
min-height: 0; /* wichtig für Scrollbar */
}
/* Rechte Spalte: Vorschau */
#pdf-preview {
flex: 1 1 auto;
min-width: 320px; /* iPad-freundlicher als 800px */
height: calc(var(--vh, 100vh) - 160px);
border: 1px solid #ccc;
background: #fff;
display: none; /* wird erst bei Klick sichtbar */
min-height: 0;
position: relative;
}
/* Preview-Toolbar / Fallback-Link */
.preview-actions {
display: none;
align-items: center;
justify-content: space-between;
gap: .5rem;
padding: .5rem .75rem;
border-bottom: 1px solid #eee;
background: #fafafa;
}
.preview-actions a,
.preview-actions button {
font: inherit;
border: 1px solid #ccc;
background: #fff;
border-radius: 4px;
padding: .35rem .6rem;
}
/* iFrame */
#pdf-preview iframe {
width: 100%;
height: calc(100% - 42px); /* Platz für .preview-actions */
border: none;
display: block;
}
/* =========================
Baum-Liste
========================= */
.pdf-tree { list-style: none; margin: 0; padding: 0; }
.pdf-tree ul { list-style: none; margin-left: 1.25em; padding: 0; display: none; }
.pdf-tree li { margin: 0.35em 0; }
/* Touch-freundliche Tap-Ziele */
.folder > .toggle {
cursor: pointer;
width: 1.5em; /* größer für Finger */
display: inline-flex;
align-items: center;
justify-content: center;
user-select: none;
margin-right: .1em;
}
.folder > .folder-label { /* gesamten Text klickbar machen */
cursor: pointer;
user-select: none;
padding: .15rem .1rem; /* kleine Hitbox-Polster */
border-radius: 3px;
}
.folder > .folder-label:active { background: rgba(0,0,0,0.05); }
.pdf-tree .meta { color: #666; }
/* Datei-Link */
.file-link {
text-decoration: none;
color: #0366d6;
}
.file-link:hover { text-decoration: underline; }
.file-link:active { opacity: .7; }
/* Buttons */
.expand-collapse {
margin-bottom: 0.5em;
display: flex;
gap: .5rem;
flex-wrap: wrap;
}
.expand-collapse button {
margin-right: 0; /* via gap */
font: inherit;
border: 1px solid #ccc;
background: #fff;
border-radius: 4px;
padding: .4rem .6rem;
}
/* Scrollbar-Optik (optional) */
.pdf-tree-container::-webkit-scrollbar { width: 10px; }
.pdf-tree-container::-webkit-scrollbar-thumb { background: rgba(0,0,0,.2); border-radius: 6px; }
/* =========================
Responsive: iPad Portrait / schmal
========================= */
@media (max-width: 1024px) {
.pdf-tree-wrapper { flex-direction: column; }
.pdf-tree-container,
#pdf-preview {
max-height: calc(var(--vh, 100vh) - 220px);
height: auto;
}
}
</style>
<!-- Buttons: Aus-/Einklappen -->
<div class="expand-collapse">
<button id="expand-all" type="button">ausklappen</button>
<button id="collapse-all" type="button">einklappen</button>
</div>
<!-- PDF-Baum und Vorschau -->
<div class="pdf-tree-wrapper">
<div class="pdf-tree-container">
<?= ModEisAnzeigeHelper::renderTree($items); ?>
</div>
<div id="pdf-preview">
<div class="preview-actions">
<span id="preview-filename" aria-live="polite"></span>
<a id="open-newtab" href="#" target="_blank" rel="noopener">in neuem Tab öffnen</a>
</div>
<!-- iFrame wird dynamisch eingesetzt -->
</div>
</div>
<script>
// --- echtes Viewport-Height-Polyfill (fix für Safari/macOS/iOS) ---
function setRealVh() {
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh * 100}px`);
}
setRealVh();
window.addEventListener('resize', setRealVh, { passive: true });
document.addEventListener('DOMContentLoaded', function () {
const treeContainer = document.querySelector('.pdf-tree-container');
const preview = document.getElementById('pdf-preview');
if (!treeContainer || !preview) return;
const previewBar = preview.querySelector('.preview-actions');
const openNewTab = document.getElementById('open-newtab');
const previewName = document.getElementById('preview-filename');
// --- (1) Verzeichnisse toggeln Caret und Label (Event Delegation, robust für iPad) ---
treeContainer.addEventListener('click', (ev) => {
const t = ev.target;
// Toggle per Caret
if (t.classList.contains('toggle')) {
const li = t.closest('li.folder');
if (!li) return;
const ul = li.querySelector(':scope > ul');
if (!ul) return;
const visible = ul.style.display === 'block';
ul.style.display = visible ? 'none' : 'block';
t.textContent = visible ? '▶' : '▼';
return;
}
// Toggle per Ordner-Label
if (t.classList.contains('folder-label')) {
const li = t.closest('li.folder');
if (!li) return;
const caret = li.querySelector(':scope > .toggle');
if (caret) caret.click();
return;
}
});
// --- (2) Alle ausklappen (mit Scroll-to-top) ---
document.getElementById('expand-all')?.addEventListener('click', () => {
document.querySelectorAll('.pdf-tree ul').forEach(ul => ul.style.display = 'block');
document.querySelectorAll('.pdf-tree .toggle').forEach(t => t.textContent = '▼');
treeContainer.scrollTo({ top: 0, behavior: 'instant' });
});
// --- (3) Alle einklappen ---
document.getElementById('collapse-all')?.addEventListener('click', () => {
document.querySelectorAll('.pdf-tree ul').forEach(ul => ul.style.display = 'none');
document.querySelectorAll('.pdf-tree .toggle').forEach(t => t.textContent = '▶');
});
// --- (4) PDF-Vorschau + Fallback-Link (iOS: iframe kann zickig sein) ---
treeContainer.addEventListener('click', (ev) => {
const a = ev.target.closest('.file-link');
if (!a) return;
ev.preventDefault();
preview.style.display = 'block';
previewBar.style.display = 'flex';
previewName.textContent = a.getAttribute('data-filename') || a.textContent.trim();
openNewTab.href = a.href;
// iFrame neu setzen
preview.querySelector('iframe')?.remove();
const iframe = document.createElement('iframe');
iframe.setAttribute('title', 'PDF-Vorschau');
iframe.src = a.href;
iframe.loading = 'lazy';
// iOS Fallback: Wenn Onload nicht in 1.5s triggert, Link oben verwenden
let loaded = false;
const t = setTimeout(() => { /* optional Hinweis einblenden */ }, 1500);
iframe.addEventListener('load', () => { loaded = true; clearTimeout(t); }, { once: true });
preview.appendChild(iframe);
}, { passive: false });
});
</script>