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