diff --git a/Web/templates/library_table.html b/Web/templates/library_table.html index bc1d773..d4665f3 100644 --- a/Web/templates/library_table.html +++ b/Web/templates/library_table.html @@ -505,6 +505,10 @@ +
Hinweis: Im Schnellmodus zuerst den Schülerausweis scannen, danach den Buch-/Mediencode. @@ -632,6 +636,11 @@ let activeStudentCardId = ''; let lastScanValue = ''; let lastScanAt = 0; + // Keyboard-scanner support (physical scanners that act as keyboard wedges) + let keyboardScannerEnabled = false; + let keyboardScanBuffer = ''; + let keyboardLastKeyAt = 0; + const KEYBOARD_SCAN_INTERCHAR_MS = 100; // max time between keystrokes to consider them one scan const canEditLibraryItems = (document.getElementById('libraryTableContainer')?.dataset.canEdit === '1'); @@ -912,6 +921,43 @@ } }); + // ========================================================================= + // Keyboard scanner handling (physical scanners that send chars then Enter) + // ========================================================================= + function keyboardScanKeydownHandler(e) { + // Only active when explicitly enabled + if (!keyboardScannerEnabled) return; + + // Ignore if focus is in an input/textarea/contenteditable to avoid interfering with typing + const active = document.activeElement; + if (active && (active.tagName === 'INPUT' || active.tagName === 'TEXTAREA' || active.isContentEditable)) return; + + const now = Date.now(); + + // If Enter/Return pressed -> finalize buffer + if (e.key === 'Enter') { + const code = keyboardScanBuffer.trim(); + keyboardScanBuffer = ''; + keyboardLastKeyAt = 0; + if (!code) return; + // Process exactly like a camera scan + handleScanSuccess(code); + return; + } + + // Only accept common printable characters; ignore modifier keys + if (e.key.length === 1) { + // If time gap too big, start new buffer + if (keyboardLastKeyAt && (now - keyboardLastKeyAt) > KEYBOARD_SCAN_INTERCHAR_MS) { + keyboardScanBuffer = ''; + } + keyboardScanBuffer += e.key; + keyboardLastKeyAt = now; + // Prevent default so scanner input doesn't accidentally move focus or trigger shortcuts + e.preventDefault(); + } + } + function handleScanSuccess(decodedText) { const scannedCode = normalizeScannedCode(decodedText); if (!scannedCode) return; @@ -1145,6 +1191,7 @@ const toggleBtn = document.getElementById('toggleScannerBtn'); const resetBtn = document.getElementById('resetCardBtn'); const modeSelect = document.getElementById('scanModeSelect'); + const keyboardToggle = document.getElementById('keyboardScannerToggle'); if (toggleBtn) { toggleBtn.addEventListener('click', async () => { @@ -1172,6 +1219,19 @@ } }); } + + if (keyboardToggle) { + keyboardToggle.addEventListener('change', () => { + keyboardScannerEnabled = !!keyboardToggle.checked; + if (keyboardScannerEnabled) { + document.addEventListener('keydown', keyboardScanKeydownHandler); + setScanStatus('Physischer Scanner aktiv (Schnellmodus empfohlen).', 'ok'); + } else { + document.removeEventListener('keydown', keyboardScanKeydownHandler); + setScanStatus('Physischer Scanner deaktiviert.', 'warn'); + } + }); + } } // Run when DOM structure is entirely ready