function initSearch() { const form = document.getElementById('searchForm'); if (!form || form.dataset.bound) return; form.dataset.bound = '1'; const esc = (value) => { if (window.escapeHtml) return window.escapeHtml(value); return String(value ?? '').replace(/[&<>"']/g, (char) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[char])); }; const encodePath = (path) => { const raw = String(path || ''); if (typeof encodeSubpath === 'function') return encodeSubpath(raw); return encodeURI(raw); }; // Function to render search results from a response object function renderResults(data) { const resultsDiv = document.getElementById('results'); const results = Array.isArray(data.results) ? data.results : []; const total = Number.isFinite(data.total) ? data.total : results.length; const shown = results.length; const remaining = Math.max(0, total - shown); resultsDiv.innerHTML = `
${fileAction}
Anzahl Downloads: ${safeHitcount}
${ perfDate !== '' ? `Datum: ${esc(perfDate)}
` : ``} ${ file.transcript_hits !== undefined ? `${fulltextLabel}: ${safeTranscriptHits} ${fulltextAction}
` : ``}Keine Treffer gefunden.
`; } } // Restore previous search response if available from localStorage const previousResponse = localStorage.getItem("searchResponse"); if (previousResponse) { try { const data = JSON.parse(previousResponse); renderResults(data); } catch (e) { console.error('Error parsing searchResponse from localStorage:', e); } } // Restore previous search word (Suchwort) if available const previousQuery = localStorage.getItem("searchQuery"); if (previousQuery) { document.getElementById('query').value = previousQuery; } // Restore previous selected category if available, otherwise default remains "Alles" const previousCategory = localStorage.getItem("searchCategory"); if (previousCategory !== null) { const radio = document.querySelector('input[name="category"][value="' + previousCategory + '"]'); if (radio) { radio.checked = true; } } // Restore previously selected filetypes (multi-select). Default to audio if none stored. const previousFiletypes = localStorage.getItem("searchFiletypes"); if (previousFiletypes) { try { const list = JSON.parse(previousFiletypes); document.querySelectorAll('input[name=\"filetype\"]').forEach(cb => { cb.checked = list.includes(cb.value); }); } catch (e) { console.error('Error parsing stored filetypes', e); document.getElementById('filetype-audio').checked = true; } } else { document.getElementById('filetype-audio').checked = true; } // Restore the checkbox state for "Im Transkript suchen" const previousIncludeTranscript = localStorage.getItem("searchIncludeTranscript"); if (previousIncludeTranscript !== null) { document.getElementById('includeTranscript').checked = (previousIncludeTranscript === 'true'); } // Form submission event form.addEventListener('submit', function(e) { e.preventDefault(); const query = document.getElementById('query').value.trim(); const includeTranscript = document.getElementById('includeTranscript').checked; const spinnerTimer = setTimeout(() => { if (typeof showSpinner === 'function') showSpinner(); }, 200); // Get the selected category radio button, if any const categoryRadio = document.querySelector('input[name="category"]:checked'); const category = categoryRadio ? categoryRadio.value : ''; // Get selected filetypes (allow multiple). Default to audio if none selected. const filetypeCheckboxes = document.querySelectorAll('input[name=\"filetype\"]'); let filetypes = Array.from(filetypeCheckboxes).filter(cb => cb.checked).map(cb => cb.value); if (filetypes.length === 0) { // enforce audio as default when user unchecked all document.getElementById('filetype-audio').checked = true; filetypes = ['audio']; } // Prevent accidental re-selection of already selected radio buttons const radios = document.querySelectorAll('input[name="category"]'); radios.forEach(radio => { radio.addEventListener('mousedown', function(e) { this.wasChecked = this.checked; }); radio.addEventListener('click', function(e) { if (this.wasChecked) { this.checked = false; this.wasChecked = false; e.preventDefault(); } }); }); // Prepare form data for the fetch request // Send the query and the category as separate parameters. const formData = new FormData(); formData.append('query', query); formData.append('category', category); formData.append('folder', document.getElementById('folder').value); formData.append('datefrom', document.getElementById('datefrom').value); formData.append('dateto', document.getElementById('dateto').value); formData.append('includeTranscript', includeTranscript); filetypes.forEach(ft => formData.append('filetype', ft)); const settleSpinner = () => { clearTimeout(spinnerTimer); if (typeof hideSpinner === 'function') hideSpinner(); }; const fetchPromise = fetch('/searchcommand', { method: 'POST', body: formData }) .then(async response => { let data = {}; try { data = await response.json(); } catch (err) { data = {}; } if (!response.ok) { const message = (data && data.error) ? data.error : `Search failed (${response.status})`; throw new Error(message); } return data; }) .then(data => { // Render the results renderResults(data); // Store the raw response in localStorage try { localStorage.setItem("searchResponse", JSON.stringify(data)); } catch (e) { console.error('Error saving searchResponse to localStorage:', e); } // Save the search word, selected category, and checkbox state in localStorage localStorage.setItem("searchQuery", query); localStorage.setItem("searchCategory", category); localStorage.setItem("searchFiletypes", JSON.stringify(filetypes)); localStorage.setItem("searchIncludeTranscript", includeTranscript); }) .catch(error => { console.error('Error:', error); const resultsDiv = document.getElementById('results'); if (resultsDiv) { resultsDiv.innerHTML = `